Sujet : Re: how cast works?
De : Keith.S.Thompson+u (at) *nospam* gmail.com (Keith Thompson)
Groupes : comp.lang.cDate : 11. Aug 2024, 01:10:42
Autres entêtes
Organisation : None to speak of
Message-ID : <87zfpj537h.fsf@nosuchdomain.example.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
User-Agent : Gnus/5.13 (Gnus v5.13)
Thiago Adams <
thiago.adams@gmail.com> writes:
Em 8/10/2024 1:14 PM, Bart escreveu:
>
Bart, Does your compiler support the `bool` type, where the value
is always either 1 or 0?
There is a bool type, but it is treated like unsigned char, so is
non-conforming.
>
I do the same in my compiler , when I transpile from C99 to C89.
I was thinking how to make it conforming.
For instance on each write.
>
bool b = 123; -> unsigned char b = !!(123);
The problem this does not fix unions, writing on int and reading from char.
I don't think you need to fix that.
In the following, I'll refer to _Bool. The same type is also called
bool if you have `#include <stdbool.h>` *or* if you have a C23 compiler.
It's always going to be possible to use type punning (memcpy, pointer
casting, union) to force a representation other than 00000000 or
00000001 into a _Bool object.
The standard doesn't have a rule that says a _Bool object can only have
the value 0 or 1. It says that *conversion* to _Bool yields a result of
0 or 1. And yes, you have to deal with that if you're translating C99
or later to C90, for both explicit and implicit conversions.
Suppose you do something like this:
_Bool b;
*(unsigned char*)&b = 0xff; // assume sizeof (_Bool) == 1
int i = b;
What is the value of b?
Under C23 rules, _Bool has 1 value bit and N-1 (typically 7) padding
bits. Any non-zero padding bits *either* create a trap representation
(C23 calls it a non-value representation) *or* are ignored when
determining the value of the object.
(_Bool can have either 254 trap representations or none. It's possible
that it might have some different number of trap representations, but
that's unlikely.)
If 11111111 is a trap/non-value representation, the behavior of
`int i = b;` is undefined; setting i to 255 or -1 are two of many
possible behaviors. If the padding bits are ignored, it must set i to 1.
Experiment shows that gcc sets i to 255 (implying that it's a trap
representation) while clang sets i to 1 (which could imply that it's not
a trap representation, but that's still a possible result of UB).
Summary:
Conversion from any scalar type to _Bool is well defined, and must yield
0 or 1.
It's possible to force a representation other than 0 or 1 into a _Bool
object, bypassing any value conversion.
Conversion from _Bool to any scalar type is well defined if the
operand is a _Bool object holding a representation of 0 or 1.
Conversion from _Bool to any scalar type for an object holding some
representation other than 0 or 1 either yields 0 or 1 (depending
on the low-order bit) or has undefined behavior.
-- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.comvoid Void(void) { Void(); } /* The recursive call of the void */