-
Notifications
You must be signed in to change notification settings - Fork 61
Description
The T-compiler and T-lang teams signed off here, that
boolhas the same representation as_Bool
where on every platform that Rust currently supports this implies that:
boolhas a size and an alignment of1,true as i32 == 1andfalse as i32 == 0, EDIT: that is always true, the valid bit patterns ofboolis what matters here, e.g., on a platform whereboolhas the same size asi8, whethertransmute::<_, i8>(true) == 1andtransmute::<_, i8>(false) == 0
These two properties are not guaranteed by Rust, and unsafe code cannot rely on these. In the last UCG WG meeting it was unclear whether we want to guarantee these two properties or not. As @rkruppe pointed out, this would be guaranteeing something different and incompatible with what T-lang and T-compiler guaranteed.
Note: any change that the UCG WG proposes will have to go through the RFC process anyways, were it might be rejected. This issue is being raised with stakeholders to evaluate whether there is something that needs changing or not, and if so, whether the change is possible, has chances to achieve consensus, etc.
The following arguments have been raised (hope I did not miss any):
-
T-lang and T-compiler did not specify which version of the C standard
_Boolconforms to. In C++20 and C20, P0907r4 (C++) and N2218 (C) specify that:booland_Boolcontain no padding bits (only value bits),1 == (int)trueand0 == (int)false.
In some of the merged PRs of the UCG we have already specified that the platform's C implementation needs to comply with some, e.g., C17 or "latest" C standard properties (e.g. for
repr(C) structlayout). If we end up requiring C20 for representation / validity ofrepr(C), we end up guaranteeing these properties. AFAICT the only property aboutboolthat would remain as implementation-defined is its size and alignment. -
In Representation of bool, integers and floating points #9 / added floating point/int summary #49 , we ended up requiring that C's
CHAR_BITS == 8. This implies that ifCHAR_BITS != 8thenboolcannot have the same representation as_Bool. Some stakeholders still wanted to be able to do C FFI with these platforms, e.g. @briansmith suggested that Rust should diagnose, e.g., usingboolon FFI on these platforms (Representation of bool, integers and floating points #9 (comment)), but that interfacing with those platforms via C FFI (e.g. against assembly) should still be possible (e.g. in a DSP whereCHAR_BITS == 16passing au16to C / assembly / ... expecting acharor 16 bit integer should be doable). -
What exactly T-lang and T-compiler actually ended up guaranteeing isn't 100% clear. In Lint for the reserved ABI of bool rust#46176 the decision seems to be that
bool == _Bool, but the PR that was actually merged only mentions thatboolhas a size of1: Document the size of bool rust#46156. This might be an oversight in the docs, and some have mention that the reference is "non-normative". @briansmith pointed out (here and here) thatboolABI (e.g. integer class or something else?), alignment, bit patterns denotingtrueandfalse, etc. don't appear to be properly documented. @gankro summarized the status quo in Rust Layout and ABIs document and mentioned that projects like Firefox rely on these extra guarantees for correctness (e.g. forbindgen, etc. to work properly, see here.
There are a couple of comments by @withoutboats that I think show both T-lang and T-compiler's rationale and the spirit behind their decision, here:
I worry that if we don't specify
boolas equivalent to C and C++ booleans, people will need to usec_boolin FFI to be cross platform compatible.I worry that if we don't specify
boolas byte sized, people will create astruct Bool(u8)to get that guarantee & keep their structs small.
and here:
People could come to the conclusion that they need a
c_booltype for their FFI to be forward compatible with platforms we don't yet support. I think defining it as the same representation as_Bool/ C++boolmakes it the least likely someone does something painful to avoid entirely hypothetical problems.
So even if the docs say that bool has a size of 1, and that's it, I believe that this last comment shows that the spirit of T-lang and T-compiler decision was to spare people from creating a c_bool type to be forward compatible on C FFI with platforms that we might never properly support.
I think that the open questions that have to be clarified, are:
- Should we require C20 compatibility for
_Bool, or do we want to stay backwards compatible with C99/11/17 ? (in this case, people can only rely on, e.g.,true == 1on targets where the platform implementation is C20 "conforming" at least w.r.t._Bool) - Do we want to require that
boolhas a size and an alignment of1? (in the hypothetical case that we ever support a platform where this is not the case, we could raise animproper_ctypewarning / error on the platform, or some other form of diagnostic, as @briansmith suggested). This would be a change incompatible withbool == _Bool, might lead people to create and use ac_booltype, etc.
cc @rkruppe @withoutboats @briansmith @gankro @joshtriplett @cuviper @whitequark @est31 @SimonSapin