On stable Rust, Rust’s
bool in FFI has the same ABI as C’s
_Bool. Apparently this, while the case, hasn’t been formally decided. I think Rust should adopt the position that the act of shipping this feature on stable Rust and keeping it shipped for an extended period of time (ever since 1.0 even?) during which deployed code has come to rely on it should under the Rust stability policy constitute commitment to this feature.
Fact I assume to be true
Based on issue comments and by observervation of my own use of
bool in FFI appearing to work on the platforms Firefox runs on, I am assuming that it’s presently true that Rust’s
bool (and pointers to it) in FFI has the same
extern "C" ABI representation as C’s
_Bool (and pointers to it).
It’s wrong to break this, so it should be documented as reliable
There is deployed code out there that assumes that Rust
extern "C" signatures maps to C’s
_Bool. It’s easy to assume that this is correct, since
rusty-cheddar generates C headers that suggest that it works that way and running the code gives the appearance of it working.
It has come to my attention that while this actually works, there hasn’t been a formal decision that it should work and, hence, there’s a proposal to make the compiler complain to programmers who are assuming that it works.
I believe this is unproductive, because a lint complaining about
bool in FFI suggests that the equivalence of
_Bool shouldn’t be relied on suggests that the equivance might get broken, but breaking it would violate the Rust stability story, so, hence, the equivalence mustn’t be broken and suggesting that it might just causes waste of effort on the part of programmers trying to figure out what to do about the lint.
Since the combination of Rust’s stability story, the act of shipping the behavior that Rust
bool in FFI is equivalent to C
_Bool on the stable channel and deployed code relying this equivalence logically has to result in commitment to keep it so, I request that it be officially documented as being so.
I’ll go ahead and address the counter-arguments I’ve seen.
bool in FFI is reserved
Counter-counter-argument: It shouldn’t matter if it’s theoretically a bug that the compiler hasn’t refused to compile code that uses
extern "C" function signatures. What should matter is that the behavior has shipped on the stable channel, has been put to use by deployed code and isn’t a soundness bug. Taking a different position would totally undermine Rust’s stability story and de facto adopt C’s approach of blaming the programmer if the programmer relies on something that seems to work but hasn’t explicitly been documented as reliable.
Counter-argument: FFI is
Counter-counter-argument: FFI is
unsafe, because it’s up to the programmer to ensure that code on the other side of the interface upholds the relevant invariants. FFI is not
unsafe as an excuse for the FFI to undergo breaking changes. In fact, while Rust’s non-FFI ABI is explicitly subject to change (and this, unlike
bool in FFI being “reserved”, is highly visibly communicated), it’s a key feature of FFI that it, in contrast to the non-FFI ABI, is not subject to breaking changes.
Counter-argument: There have been soundness fixes
Counter-counter-argument: These are opposite cases. A soundness bug threatens the whole value proposition of Rust and the breakage from the fix tends to be theoretical. In this case, it’s in practice a feature that’s in real use that
bool maps to
_Bool, so the breakage would be real, but changing it would “fix” a theoretical concern.
Counter-argument: There exist C implementations whose
_Bool is too weird to commit Rust’s
bool to match
Counter-counter-argument: Rust’s stability story should mean that there’s a commitment not to break what has already shipped. This means that Rust’s
bool in FFI has to continue to match C’s
_Bool on the Windows and System V-ish systems that Rust has already been deployed on. Suggesting that this part might be subject to change makes programmers waste time. OTOH, warning programmers about niche platforms that Rust might support in the future would be a gross misbalancing by putting theoretical future niche concerns ahead of programmer productivity on actual present mainstream and not-quite-so-mainstream systems. Rust already, quite appropriately, forgoes interop with some imaginable C implementations–most notably those that don’t provide two’s complement signed integers. If in the future Rust actually ends up targeting platforms whose C ABI is too weird for Rust’s
bool to match, dealing with that mismatch should be a problem for developers in that niche to solve and shouldn’t spill over to inconvenience everyone.