Hacker News new | ask | show | jobs
by Rusky 3074 days ago
What would make this "declarative way to talk about C interfaces" less error prone than something like this?

    extern fn read(fd: c_int, buf: *mut c_char, len: usize) -> isize;

    pub fn read(fd: c_int, buf: &mut [c_char]) -> isize {
        unsafe { read(fd, buf.as_mut(), buf.len()) }
    }
Further, note that this is insufficient for an idiomatic Rust API. You would also want to wrap the file descriptor (perhaps not for all C APIs) and the return value (definitely applies to all C APIs). So it would really look more like this:

    pub struct File { fd: c_int }

    impl File {
        pub fn read(&self, buf: &mut [u8]) -> Result<usize, ReadError> {
            let r = unsafe { read(self.fd, buf.as_mut(), buf.len()) };
            if r == -1 {
                Err(ReadError::from(errno))
            } else {
                Ok(r as usize)
            }
        }
    }
I can certainly imagine a way to do that declaratively, but not in a way that helps even this most basic of examples. (Also, note that constructing raw pointers is completely safe- `as_mut` for example.)
1 comments

That's not bad. It would be useful to be able to use some kind of "C slice" in an extern fn declaration, so you could talk about arrays, rather than pointers. Same function call code, but more Rust-line syntax. Then you don't need unsafe imperative code at all.

This would put all the memory-risky stuff in declarations of external functions.