5 ms·
Given that C is a subset of C++ (meh), can you use this to generate safe bindings for C? Most C integration recommendations I've seen suggest using bindgen, bu
by cjg 5y ago
Given that C is a subset of C++ (meh), can you use this to generate safe bindings for C?
Most C integration recommendations I've seen suggest using bindgen, but that doesn't give safe bindings.
- maxnoe 5y agoI guess this relies on reference counting via smart pointers
- pcwalton 5y agocxx doesn't rely on reference counting. If you're using reference counted smart pointers in C++, then cxx can bind to them. But it won't impose the overhead of reference counting if you aren't already using it.
- pornel 5y agoNot really. The library internally already uses a C ABI, because that's what both C++ and Rust can agree on, but that ABI is not for consumption from C. The point of this library is to preserve higher-level Rust/C++ features like destructors, generic containers, smart pointers, and other things that C can't express.
- cjg 5y agoI meant generating a safe Rust API for existing C code rather than calling an existing Rust API from C.
- pornel 5y agoIn that direction it's difficult, because C source code doesn't contain machine-readable information about ownership (who and when can free a pointer), lifetimes, or thread safety. C annotations for aliasing, nullability, and lenghts of arrays (malloced, not VLA) are very basic, and rarely used. Lots of C code isn't even const-correct. Some of these properties could be deduced by a Sufficiently Smart Compiler, but you'd probably need an A.I. that reads the docs.
- girvo 5y agoI’m imagining an interactive tool where it asks those questions of the developer when generating the binding code (c2nim is what I use regularly)
- dangerbird2 5y agobindgen[1] already exists to autogenerate a rust API from c headers. It's inherently unsafe because C code is inherently unsafe. In particular, there is no language constructs like destructors or constructors, so you can't naively create a C-based API that can prevent memory/resource leaks and use after free errors. While C++ does have the same issues as C with unsafe pointer semantics, it does have constructors, destructors, and other features that map almost perfectly with Rust's RAII-based resource management, making it pretty easy to generate a safe(ish) rust interface. In practice, it's pretty easy to create a safe rust API from a C library: use bindgen to create the low-level unsafe API, then create rust wrappers using the ad-hoc creation and descruction library functions to implement RAII. [1] https://rust-lang.github.io/rust-bindgen/ https://rust-lang.github.io/rust-bindgen/
- bluejekyll 5y agoThe problem is that it’s not easy to give safe bindings into C because C’s memory model is all unsafe by Rusts definitions. You have to manually inspect the C usage of pointers and such to create the semantics in Rust that make its usage safe.
- kmeisthax 5y agoProbably not, and the reason why bindgen code is marked `unsafe` is because that's the default for all Rust FFI. You can't automatically examine a set of C function signatures and conclude whether or not they're safe - so it's sound to just treat them all as `unsafe` and have the developer document what their safety requirements are, or provide wrapper functions that enforce safety checks at runtime.
- woodruffw 5y agoIf we're being pedantic (and pedantry matters for safety!) C hasn't been a subset of C++ for a while: they have different type aliasing rules (well-defined aliases in C can be UB in C++), different direct initialization syntaxes, flexible array members, etc.
- int_19h 5y agoTo be even more pedantic, C hasn't ever been a subset of C++, if only because of implicit-cast-to-void* that C has but C++ doesn't.
- cjg 5y agoMost of the answers to this question seem to make the argument that you could not automatically generate safe Rust wrappers for an existing C library because it would be impossible to automatically know the safety requirements for a C API. That's also true, in general, for C++, but CXX is nevertheless attempting to solve that problem. CXX requires you to give some extra information when declaring the bridge. Presumably that can allow things to be less automatic. I'm guessing that the reality is that if your C++ code is relatively idiomatic then CXX will work with it, but stray too far from idiomatic C++ - i.e. towards a C-style interface and CXX won't be able to do such a good job. But it would be good to hear something more definitive.
- deleted 5y ago[deleted]