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

Clarify the representation of Boolean value true #898

Merged
merged 2 commits into from
Aug 17, 2023

Conversation

RexJaeschke
Copy link
Contributor

@RexJaeschke RexJaeschke commented Aug 16, 2023

In §8.3.3 of the current spec (draft-v7), we say that false is all-bits zero. And as we say nothing about the representation of true that is implicitly unspecified. That is problematic, as we should at least say that the two values need to be distinct. In fact, the CLI spec states the following:

The System.Boolean value type represents the logical values true and false. The size of this type is 8 bits, the representation of false is all-bits-zero, and the representation of true is unspecified except that it shall have at least one bit set.

I'm thinking that VB might use -1/255 for true. In any event, the CLI doesn't exclude a CLS-compliant language having true be 2, 3, 4, 5, ....

This PR makes the representation explicitly unspecified, and requires the two values to differ.

@BillWagner https://learn.microsoft.com/en-us/dotnet/api/system.boolean?view=net-7.0#Binary states

The byte's low-order bit is used to represent its value. A value of 1 represents true; a value of 0 represents false.

This doesn't sound right for all possible conforming implementations. If in a C# method that is passing a bool to/from some other language, more than 1 bit could be used for the representation of true, allowing the low bit to be zero for both true and false, for example if true were any even number.

Copy link
Contributor

@Nigel-Ecma Nigel-Ecma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here be dragons ;-)

Just questions & observations – no suggested changes per se.

First I’m not sure §8.3.3 Default constructors guarantees that false is represented by all bits zero, or any of the other types are all bits zero either, though that might be specified elsewhere. What it is saying is that the default value is a (not “the” as some types such as FP ones may have more than one…) “zero” for the type and what that zero is – false for bool, +0.0 (not -0.0) for FP types.

The CLI defines a flase-value as all bits zero and a true-value as any other 8-bit value with at least one 1 bit.

Consider r & s are bool, assigned the values 0x0F & 0xF0 respectively, the following is the output of a little C# test code (VS 2022 with LangVersion 7.3):

*(byte *)&r => 15
*(byte *)&s => 240
r => True
s => True
r == s => False
r && s => False
r ? 't' : 'f' => t
s ? 't' : 'f' => t

So any non-zero value is true sometimes

Maybe we should tie true to 1 (which is what is being used)?

Also is this “unspecified” if it is some value in a specified small range? (I don't know offhand)

@Nigel-Ecma
Copy link
Contributor

Continuing from previous I thought I’d poke the sleeping dragon a bit more:

(r && true) && (s || false) => True

A few other ones tried produced similar results. I postulate you need to combine a bool with a value other than 0x0 or 0x1 with a literal as above to get correct results.

Bool, a type one false, one true, and 254 Schrödinger’s – and its how you look not just if you do!

Conclusion: define false as 0x0, true as 0x1, and state it is undefined behavior if any value in the range 0x2 – 0xFF is used; unless somebody wants to fix the compiler/CIL…

Copy link
Contributor

@jskeet jskeet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's hard to argue with the correctness of this, even if we'd like to be able to say more :)

Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also agree.

Let's :shipit:

@BillWagner BillWagner merged commit fc6b084 into dotnet:draft-v7 Aug 17, 2023
@BillWagner BillWagner deleted the Rex-representation-of-true branch August 17, 2023 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants