Sujet : Re: Representation of _Bool
De : learningcpp1 (at) *nospam* gmail.com (m137)
Groupes : comp.lang.cDate : 19. Jan 2025, 03:30:02
Autres entêtes
Organisation : novaBBS
Message-ID : <0f5ec645511128c21c90fb0688247e60@www.novabbs.com>
References : 1 2 3
User-Agent : Rocksolid Light
On Fri, 17 Jan 2025 21:34:53 +0000, Keith Thompson wrote:
The message being referred to is one I posted Sun 2021-05-23, with
Message-ID <87tums515a.fsf@nosuchdomain.example.com>. It's visible on
Google Groups at
<https://groups.google.com/g/comp.lang.c/c/4FUlV_XkmXg/m/OG8WeUCfAwAJ>.
>
As others have suggested, please include attribution information when
posting a followup. You don't need to quote the entire message,
but provide at least some context, particularly when the parent
message is old.
>
Hi Keith,
Sorry for the confusion, I am new to the platform and had not realised
that I needed to quote your post in my reply.
>
The definition of non-value representation rules out object
representations that represent a value of the object type from being
non-value representations. So it seems to be stricter than the
definition of trap representation, which does not seem to rule out such
object representations from being trap representations. Is this
interpretation correct?
>
I don't believe so. As far as I can tell, a "non-value
representation" (C23 and later) is exactly the same thing as a "trap
representation" (C17 and earlier). The older term was probably
considered unclear, since it could imply that a trap is required.
In fact, reading an object with a trap/non-value representation
has undefined behavior, which can include yielding the value you
might have expected.
>
The reason I thought they were different was because the definition of
trap representation uses the phrase "need not", i.e. a trap
representation is an object representation that **need not** represent a
value of the object type. I read this as saying that a trap
representation could be an object representation that represents a value
of the object type, **or** it could be one that does not. This seemed
more permissive than the definition of non-value representation, which
uses the phrase "does not", i.e. a non-value representation is an object
representation that *does not* represent a value of the object type. I
took that as meaning that object representations that do represent a
value of the object type (such as those 254 representations of `_Bool`,
assuming a width of 1) are excluded from being classed as non-value
representations. But I understand now that that is not the case.
Editions of the C standard earlier than C23 were not entirely
clear about the representation of _Bool.
Yes, confusingly, I could not find anything about the width of a `_Bool`
in C99, and C11 and C17 only talk about it in a footnote all the way
down in 6.7.2.1:
- C11 final draft, footnote 122:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=131- C17 final draft, footnote 124:
https://web.archive.org/web/20181230041359/
http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#page=100Typically in C17 and earlier, and always in C23, _Bool/bool will
have exactly 1 value bit and CHAR_BIT-1 padding bits. Padding bits
do not contribute to the value of an object (so 0 and 1 are the
only possible values), but non-zero padding bits *may or may not*
create trap/non-value representations. (A gratuitously exotic
implementation might use a representation other than 00000001 for
true, but 00000000 is guaranteed to be a representation for 0/false.)
>
As far as I can tell, the standard is silent on whether a bool object
with non-zero padding bits is a trap/non-value representation or not.
>
I wrote a test program to explore how bool is treated. It uses
memcpy to set the representation of a bool object and then prints
the value of that object. Source is at the bottom of this message.
>
If bool has no non-value representations, then the values of the
CHAR_BIT-1 padding bits must be ignored when reading a bool object,
and the value of such an object is determined only by its single
value bit, 0 or 1. If it does have non-value representations,
then reading such an object has undefined behavior.
>
With gcc 14.2.0, with "-std=c23", all-zeros is treated as false
when used in a condition and all other representations are treated
as true. Converting the value of a bool object to another integer
type yields the value of its full 8-bit representation. If a bool
object holds a representation other than 00000000 or 00000001,
it compares equal to both `true` and `false`.
>
This implies that bool has 1 value bit and 7 padding bits (as
required by C23) and that it has 2 value representations and 254
trap representations. The observed behavior for the non-value
representations is the result of undefined behavior. (gcc -std=c23
sets __STDC_VERSION__ to 202000L, not 202311L. The documentation
acknowledges that support for C23 is experimental and incomplete.)
>
With clang 19.1.4, with "-std=c23", the behavior is consistent
with bool having no non-value representations. The 7 padding bits
do not contribute to the value of a bool object. Any bool object
with 0 as the low-order bit is treated as false in a condition and
yields 0 when converted to another integer type,. Any bool object
with 1 as the low-order bit is treated as true, and yields 1 when
converted to another integer type. I presume the intent is for bool
to have 256 value representations and no non-value representations
(with the padding bits ignored as required), but it's also consistent
with bool having non-value representations and the observed behavior
being undefined. It's not possible to determine with a test program
whether the output is the result of undefined behavior or not.
Compiling the last snippet in this article:
https://www.trust-in-soft.com/resources/blogs/2016-06-16-trap-representations-and-padding-bits,
with Clang 19.1.0 and options "-std=c23 -O3 -pedantic" seems to show
that Clang does treat `_Bool` as having 2 value representations and 254
non-value representations (see here:
https://gcc.godbolt.org/z/4jK9d69P8).
Thank you so much for taking the time to provide such a thorough
analysis. It really clears things up for me.
--