Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the size of bool #46156

Merged
merged 1 commit into from Feb 3, 2018

Conversation

Projects
None yet
@SimonSapin
Copy link
Contributor

SimonSapin commented Nov 21, 2017

No description provided.

@SimonSapin

This comment has been minimized.

Copy link
Contributor Author

SimonSapin commented Nov 21, 2017

It is always 1, right?

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Nov 21, 2017

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @BurntSushi (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Nov 21, 2017

This is historically not guaranteed on purpose rust-lang/rfcs#954

We discussed this at triage today, and the general feeling was that we probably don't want to commit to the representation of Rust's bool type. We may want to apply future optimizations to the representation or semantics, and this sort of restriction may prevent us from doing so.

/cc @rust-lang/lang

See also rust-lang/rfcs#992

@rkruppe

This comment has been minimized.

Copy link
Member

rkruppe commented Nov 21, 2017

Worth noting that rust-lang/rfcs#954 proposed far more than documenting the size, it proposed guaranteeing a encoding of true and false as bytes and furthermore ties it to the C ABI (it's legal for the C compiler to make _Bool larger than one byte, although in practice that doesn't seem to be common).

In contrast, guaranteeing a size_of of 1 seems entirely harmless, because what else could it sensibly be? (Edit: See correction below) Even if future Rust compiler could sometimes packs bools in unused bits in aggregates, a size_of of 0 would break things such as Box::new(true). A larger size_of would be legal, but would not be an "optimization".

@durka

This comment has been minimized.

Copy link
Contributor

durka commented Nov 21, 2017

The values true=1, false=0 are documented: https://doc.rust-lang.org/reference/behavior-considered-undefined.html

@bluss

This comment has been minimized.

Copy link
Contributor

bluss commented Nov 21, 2017

The reference is not official rust docs and it is not a real reference yet, unfortunately.

@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Nov 21, 2017

@bluss then remove that statement from the reference. And no it is official documentation. Otherwise why is it on the doc.rust-lang.org domain?

@bluss

This comment has been minimized.

Copy link
Contributor

bluss commented Nov 21, 2017

Nightly version has a better banner and a link to the nursery repo where it's developed: https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html

@durka

This comment has been minimized.

Copy link
Contributor

durka commented Nov 21, 2017

Then we should close this PR as writing down the size of bool won't have any weight... is there a list of "decisions that have actually been made and can be trusted"?

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Nov 21, 2017

@durka IMO the authoritative Rust documentation is the standard library's documentation, as the guarantees it specifies are part of the library, and therefore part of Rust's stability guarantees.

@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Nov 21, 2017

Hmm, so the impact of this change would be to put the compile-time-validity of transmute::<bool, u8> inside the stability guarantee? I understand writing code that relies on size_of::<u8>() == 1; is it particularly valuable to be able to rely on size_of::<bool>() == 1 in unsafe?

est31 added a commit to est31/rust that referenced this pull request Nov 21, 2017

Lint for the reserved ABI of bool
The ABI of bool is reserved, see these links:

* rust-lang/rfcs#954 (comment)
* rust-lang#46156 (comment)
* rust-lang/rfcs#992

Currently the improper_ctypes lint is inconsistent
with that position by treating bools as if they had
a specified ABI.

To fix this inconsistency, this changes treatment of
bools by the lint.

This might break some code, so possibly it has to
be phased in slowly...
@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Nov 21, 2017

So as the ABI of bool seems to be not specified, please see my PR #46176 to lint about bool in FFI usage.

@egilburg

This comment has been minimized.

Copy link

egilburg commented Nov 21, 2017

Perhaps document i128 and u128 too?

@rkruppe

This comment has been minimized.

Copy link
Member

rkruppe commented Nov 22, 2017

It appears that C doesn't specify the size of _Bool (it just has to be able to store 0 and 1), so if we want to specify bool as being compatible with _Bool that would theoretically clash with documenting the size to be 1. I say "theoretically" because I'm not aware of a platform that makes _Bool larger (other than possibly architectures where char isn't 8 bit, but those aren't really supported by Rust anyway).

est31 added a commit to est31/rust that referenced this pull request Nov 22, 2017

Lint for the reserved ABI of bool
The ABI of bool is reserved, see these links:

* rust-lang/rfcs#954 (comment)
* rust-lang#46156 (comment)
* rust-lang/rfcs#992

Currently the improper_ctypes lint is inconsistent
with that position by treating bools as if they had
a specified ABI.

To fix this inconsistency, this changes treatment of
bools by the lint.

This might break some code, so possibly it has to
be phased in slowly...
@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Nov 22, 2017

IMO the size of bool should be defined as the same as the size of _Bool on that platform, which we should helpfully document as being one byte essentially always.

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Nov 22, 2017

Basically I think we should just accept RFC 954 at this point.

@Havvy

This comment has been minimized.

Copy link
Contributor

Havvy commented Nov 22, 2017

I added the table in #44648 and checked what people said on IRC around the time. I'm not seeing any reference to bool in either location. Looks like I completely missed it on oversight.

I do have a reference PR where I added it though, but it looks like I'll have to remove that line. 😣

About the UB section of the reference — it's immaterial to this discussion. It's stating that the valid values of bool are 0 and 1. There's nothing about the size of the type. Or are we even saying that we can have bools where false is not 0 and true is not 1?

@vojtechkral

This comment has been minimized.

Copy link
Contributor

vojtechkral commented Nov 22, 2017

IMO the size of bool should be defined as the same as the size of _Bool on that platform

I wonder why should bool be treated differently than integer types. With integer types, Rust defines its types such that they are as sane and consistent across platforms as possible (ie. i32, usize etc.) and relies on libc to provide C FFI interop types, which seems to work reasonably well. Why isn't the same strategy applied to bool? That is, keep it sane inside Rust (ie. sized 1) and provide a libc bool type for C FFI.

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Nov 22, 2017

That also seems fine.

I think the larger thrust of my objective is that we should stop delaying action based on theoretical concerns. There are neither viable optimizations nor major platforms which conflict with specifying the obvious representation of bool. Any solution in which we specify the repr of boolean as what it has been and will always be on major platforms is good.

@SimonSapin

This comment has been minimized.

Copy link
Contributor Author

SimonSapin commented Nov 24, 2017

hsivonen wrote in a thread that mentioned this PR:

I'm so glad Rust committed to two's complement despite it ruling out FFI interop with some C implementations. I wish today's Rust had more of the “UTF-8 everywhere, two's complement everywhere” attitude.

I think that’s a good point, and we should decide that Rust’s bool always has the obvious representation. If they turn out to be real, FFI concerns can be addressed with conversions in the libc crate.

@kennytm kennytm added the T-lang label Nov 24, 2017

@aturon aturon added the I-nominated label Nov 28, 2017

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Nov 28, 2017

Nominated for lang team discussion.

@kennytm

This comment has been minimized.

Copy link
Member

kennytm commented Dec 13, 2017

Hi @rust-lang/lang, triage ping. Is there any update on this? Should this PR (and also #46176) be kept open until a decision is reached?

@nicodemus26

This comment has been minimized.

Copy link

nicodemus26 commented Dec 17, 2017

@vojtechkral It would seem that bool is already the C FFI interop type. A new one-sized type u1 would maybe make sense, but would it complicate the ecosystem? u1 and bool should be fully bijective but sometimes sized differently.

bool is to usize as u1 is to u64 on a 64-bit arch?

As an aside, it would be pretty nice to have u1 arrays and slices compile to space-efficient bitmaps!

@SimonSapin

This comment has been minimized.

Copy link
Contributor Author

SimonSapin commented Dec 17, 2017

As an aside, it would be pretty nice to have u1 arrays and slices compile to space-efficient bitmaps!

You’re looking for https://crates.io/crates/bit-vec. This is not possible with [T; N] / [T] / Vec<T> because in these each element needs to have a distinct address because indexing returns &T or &mut T.

@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Dec 17, 2017

As an aside, it would be pretty nice to have u1 arrays and slices compile to space-efficient bitmaps!

C++ has experience with that, and it turned out to be better as opt-in instead of magic: https://isocpp.org/blog/2012/11/on-vectorbool

@kennytm

This comment has been minimized.

Copy link
Member

kennytm commented Jan 10, 2018

Triage ping @rust-lang/lang! It seems we still haven't got a clear decision...

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jan 18, 2018

Cross-posting from the internals thread:

We finally got around to discussing this in the @rust-lang/lang meeting. We had the following questions, perhaps someone may be in a position to answer authoritatively:

  • Are there any extant platforms where _Bool in the C ABI is permitted to take values other than 0 or 1?
    • How I understood prior answers is "no, truth-y values will coerce to 1"
  • Does the C standard permit platforms where _Bool is permitted to take values other than 0 or 1?
  • Side question: are there extant platforms where sizeof(_Bool) != 1 ?
    • We believe the C standard permits other sizes, but weren't clear if anyone took advantage of that freedom.

Our preference is to define bool as _Bool. This would be what most people expect and avoid massive breakage. If the C standard requires values of 0 or 1, then there seems to be basically no drawback. Otherwise, it implies a potential performance pitfall on matches (matches on bools, mind you) but doesn't seem like a huge problem. Still, it'd be good to know the answers to those questions before reaching a final consensus.

Relevant to this RFC, @SimonSapin or others, do you think that defining bool to be 1 byte everywhere is better than _Bool? If so, it'd be good to discuss the case for that further. (I confess to not having read every comment here, so I'd appreciate pointers into the discussion.)

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Jan 18, 2018

Additional question for the list:

  • Are there any extant platforms where C++ bool and C _Bool have different ABIs?

C _Bool is a late addition to the language that is largely unused in C interfaces, so C++ bool should be much more important from practical FFI point of view.

@vojtechkral

This comment has been minimized.

Copy link
Contributor

vojtechkral commented Jan 19, 2018

@nikomatsakis

Does the C standard permit platforms where _Bool is permitted to take values other than 0 or 1?

From N1570, §6.2.5:

An object declared as type _Bool is large enough to store the values 0 and 1.

§6.3.1.2:

When any scalar value is converted to _Bool, the result is 0 if the value compares equal
to 0; otherwise, the result is 1. 59)

Ie. I believe from the standard's point of view _Bool can only have values 1 and 0.

cppreference.com also notes a consequence:

Note that conversion to _Bool does not work the same as conversion to other integer types: (bool)0.5 evaluates to 1, whereas (int)0.5 evaluates to ​0​.

@SimonSapin

This comment has been minimized.

Copy link
Contributor Author

SimonSapin commented Jan 19, 2018

@SimonSapin or others, do you think that defining bool to be 1 byte everywhere is better than _Bool?

(Replying since I’m mentioned by name. “Better” is a big word. I have no idea. I submitted this PR because it had not occurred to be that this could be otherwise.)

@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Feb 2, 2018

The FCP has been resolved: #46176 (comment)

Please merge this now!

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Feb 2, 2018

@bors r+

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Feb 2, 2018

📌 Commit 219ba51 has been approved by withoutboats

@kennytm

This comment has been minimized.

Copy link
Member

kennytm commented Feb 2, 2018

@bors rollup

kennytm added a commit to kennytm/rust that referenced this pull request Feb 2, 2018

bors added a commit that referenced this pull request Feb 2, 2018

Auto merge of #47962 - kennytm:rollup, r=kennytm
Rollup of 10 pull requests

- Successful merges: #46156, #47753, #47829, #47842, #47898, #47914, #47916, #47919, #47942, #47951
- Failed merges:

bors added a commit that referenced this pull request Feb 2, 2018

Auto merge of #47962 - kennytm:rollup, r=kennytm
Rollup of 9 pull requests

- Successful merges: #46156, #47829, #47842, #47898, #47914, #47916, #47919, #47942, #47951
- Failed merges: #47753

bors added a commit that referenced this pull request Feb 3, 2018

Auto merge of #47962 - kennytm:rollup, r=kennytm
Rollup of 10 pull requests

- Successful merges: #46156, #47829, #47842, #47898, #47914, #47916, #47919, #47942, #47951, #47973
- Failed merges: #47753

@bors bors merged commit 219ba51 into rust-lang:master Feb 3, 2018

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@Havvy Havvy referenced this pull request Feb 3, 2018

Merged

Add size of bool #233

@SimonSapin SimonSapin deleted the SimonSapin:patch-14 branch Mar 30, 2018

@nirbheek nirbheek referenced this pull request May 27, 2018

Closed

Document size of bool #1379

@gnzlbg gnzlbg referenced this pull request Dec 6, 2018

Closed

bool == _Bool ? #53

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.