Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upWant a compiler warning if I repr(C) a bool #1982
Comments
This comment has been minimized.
This comment has been minimized.
|
Isn't |
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Apr 26, 2017
•
|
Neither C99, nor C11 standard specifies what
In my non-expert opinion, using the type on any sort of ABI boundary is something to be avoided like a plague. |
This comment has been minimized.
This comment has been minimized.
|
gboolean predates _Bool :) I had this buggy code:
and I assumed that on the C side it would look like
That doesn't work; field2 ends up with garbage in the high bits. However, "importing" C functions for calling from Rust seemed to work fine:
The C prototype is
In the case of the struct, Rust doesn't know what my C struct will look like. Maybe emit a compiler warning until the repr(C) for bool is actually documented (I was running on an assumption like "surely it's just a C int"). In the case of the extern fucntion, declaring a return type which is not something from libc::* is clearly suspect, I think... |
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Apr 26, 2017
I'm guessing this works due to the fact that C promotes parameters/retvals smaller than |
This comment has been minimized.
This comment has been minimized.
Yes, that makes a lot of sense. Now I'm wondering if it works (and the tests work) on my little-endian x86 when Rust picks up the bool from the low bits of the promoted int - but it wouldn't work on big endian :) |
This comment has been minimized.
This comment has been minimized.
comex
commented
Apr 26, 2017
•
|
It doesn't seem particularly surprising to me that the C equivalent of Rust (Also known as edit: also, repr(C) isn't actually relevant here. |
This comment has been minimized.
This comment has been minimized.
As far as I understand, |
This comment has been minimized.
This comment has been minimized.
Sorry, dinosaur here. AFAICT stdbool.h is from c99, and gboolean is from 1996 or thereabouts :) |
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Apr 27, 2017
|
Now, the question is, does Rust guarantee that Rust What I would suggest is this:
|
This comment has been minimized.
This comment has been minimized.
|
@le-jzr C is not the only language that Rust FFIs with. In fact, into the future, I would imagine that C++ is the far more important language for Rust to FFI with, and C++ has fully integrated (I'd also note that all C types (except the |
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Apr 27, 2017
•
|
@ubsan That's just more reason not to allow plain |
This comment has been minimized.
This comment has been minimized.
CryZe
commented
Apr 27, 2017
•
|
I actually hit this issue just yesterday, where both Rust's and C#'s bool are 1 byte, but C# assumes bools are 4 bytes during FFI, so my functions always returned true. |
This comment has been minimized.
This comment has been minimized.
|
@le-jzr I don't like making Rust worse because other languages made the wrong choice. C's |
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Apr 27, 2017
|
@ubsan I don't understand what you mean by "making Rust worse". Current state is strictly worse -- we can use |
This comment has been minimized.
This comment has been minimized.
|
It does seem that
Which appears to me to be compatible with Rust's definition of a What happens if there is an ABI that doesn't have the same guarantees as Rust though? Say, one where it does guarantee to pass a parameter of type extern fn foo(bar: c_int) {
let bar = bar != 0;
...
}which would hopefully get optimised out, but could potentially introduce a slight hidden runtime cost. An alternative could be to not allow extern fn foo(bar: c_Bool) {
let bar = bar.to_bool();
...
}Which on x86-64 could be a no-op, and on the hypothetical incompatible ABI could be a slight explicit runtime cost if not optimised out. For all I know this might already be taken care of by LLVM just by how Rust defines its |
This comment has been minimized.
This comment has been minimized.
|
A
This cost is only taken on |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 I've updated the first code block and preceding paragraph to try and remove any implication that I think a If there are already hidden runtime costs in |
This comment has been minimized.
This comment has been minimized.
erkinalp
commented
Jun 3, 2017
|
GCC and LLVM |
This comment has been minimized.
This comment has been minimized.
|
Sure enough, we need better documentation on how Rust types match ABI types, both in |
Centril
added
the
T-compiler
label
Dec 6, 2017
vext01
referenced this issue
Dec 7, 2017
Closed
Use a bool return type for traceme_stop_tracer(). #9
This comment has been minimized.
This comment has been minimized.
vext01
commented
Dec 11, 2017
|
It sounds to me like the Rust FFI should guarantee that it's native For other languages that want to map their Booleans at the ABI level, wouldn't it make sense to have a separate (external) crate defining a specialised bool type? In other words |
This comment has been minimized.
This comment has been minimized.
|
Cross-referencing more discussion @ rust-lang/rust#46176 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Rust Link to the decision: rust-lang/rust#46176 (comment) |
petrochenkov
closed this
Feb 11, 2018
This comment has been minimized.
This comment has been minimized.
|
I'm fine with closing this now that bool matches the platform's C _Bool. |
federicomenaquintero commentedApr 26, 2017
While #992 gets resolved, I would love to have a compiler warning whenever I naively assume that repr(C) for bool will look like any C type in particular.
Example: In librsvg, I assumed that bool would repr(C) as int, and therefore as gboolean (Glib's name for int-as-boolean values). It worked... passing values from C to Rust, until it didn't, passing values from Rust to C :)