3 ms·
Impossible in safe rust. But would a sqlite port limit itself to safe rust? (As a side note wrt integer overflows, rust only makes it easier to detect them du
by dathinab 5y ago
Impossible in safe rust.
But would a sqlite port limit itself to safe rust?
(As a side note wrt integer overflows, rust only makes it easier to detect them during tests and provides neat methods for integer overflow aware code, but just that.)
Anyway I'm surprised that there where more "preventable" bugs then I expected.
- woodruffw 5y ago> But would a sqlite port limit itself to safe rust? I suppose they wouldn't have to, but why would they bother with unsafe? They proudly announce how few system APIs and syscalls they depend on, so they have no need for that (assuming they chose to not use any number of safe wrappers). Complicated self-referential data structures, perhaps, but that again is the kind of thing that could be exhaustively tested and tucked into a safe interface. And yes, you're absolutely right about integers: Rust itself is not going to save you in release builds. But it does avoid a major source of overflows in C (implicit conversions and promotions), and has explicit, fallible APIs that are easy to enforce as a lint.
- zimpenfish 5y ago> but why would they bother with unsafe? Wouldn't they need unsafe in order to interface with the outside world via their libsqlite persona? Which, I think, is how most of the world consumes their sqlite - embedded in some other language as a library?
- woodruffw 5y agoYou can export a C API in safe Rust. You might a small amount of unsafe code at any boundary where the C API takes pointers instead providing them, but that again is the kind of thing that can be safely encapsulated and tested.
- dathinab 5y ago> small amount of unsafe code You can for example have a C API accepting a Option<&mut A> if A is repr(c) and sized. This is possible due to the guarantees &mut A has about it's representation (if A is..) and the guarantees `Option` has about it's representation wrt. non-null values. While such pattern exposes a often fully safe rust C-ABI API it has some drawbacks mainly that C is required to make sure the pointer they pass in is valid (null or aligned, allocated and initialized). You can take this a step further an only accept a `&mut A` BUT that is a bit dangerous as now C calling rust with a null-pointer leads to unsound rust, as rust assumes &mut A is never null. Another gotcha is wrt. owned heap allocated data, as you need to make sure the same alocator is used for allocating and de-allocating it. Again nothing new, but in C you often doge that issue. (E.g. if you allocate, and initialize a *A in C and then pass it to rust as a Box<A> you need to be very careful that you never drop that box in rust). Through Rust is currently getting support for keeping track of non-default/non-global allocators in the standard library, and you could always setup a global/default allocator which defers to libcs malloc/free.