问题
I was trying to write some macros for type safe use of _Bool
and then stress test my code. For evil testing purposes, I came up with this dirty hack:
_Bool b=0;
*(unsigned char*)&b = 42;
Given that _Bool
is 1 byte on the implementation sizeof(_Bool)==1
), I don't see how this hack violates the C standard. It shouldn't be a strict aliasing violation.
Yet when running this program through various compilers, I get problems:
#include <stdio.h>
int main(void)
{
_Static_assert(sizeof(_Bool)==1, "_Bool is not 1 byte");
_Bool b=0;
*(unsigned char*)&b = 42;
printf("%d ", b);
printf("%d", b!=0 );
return 0;
}
(The code relies on printf
implicit default argument promotion to int
)
Some versions of gcc and clang give output 42 42
, others give 0 0
. Even with optimizations disabled. I would have expected 42 1
.
It would seem that the compilers assumes that _Bool
can only be 1
or 0
, yet at the same time it happily prints 42
in the first case.
Q1: Why is this? Does the above code contain undefined behavior?
Q2: How reliable is sizeof(_Bool)
? C17 6.5.3.4 does not mention _Bool
at all.
回答1:
Q1: Why is this? Does the above code contain undefined behavior?
Yes, it does. The store is valid, but subsequently reading that as a _Bool
is not.
6.2.6 Representations of types
6.2.6.1 General
5 Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. [...]
Q2: How reliable is
sizeof(_Bool)
? C17 6.5.3.4 does not mention_Bool
at all.
It will reliably tell you the number of bytes that are needed to store one _Bool
. 6.5.3.4 also doesn't mention int
, but you're not asking whether sizeof(int)
is reliable, are you?
来源:https://stackoverflow.com/questions/52163870/bool-type-and-strict-aliasing