我试图编写一些宏以确保 _Bool
的类型安全使用,然后对我的代码进行压力测试。为了邪恶的测试目的,我想出了这个肮脏的黑客:
_Bool b=0;
*(unsigned char*)&b = 42;
鉴于 _Bool
在实现 sizeof(_Bool)==1
) 上是 1 个字节,我看不出这个 hack 如何违反 C 标准。它不应该是严格的别名违规。
然而,当通过各种编译器运行这个程序时,我遇到了问题:
#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;
}
(代码依赖于 printf
隐式默认参数提升为 int
)
某些版本的 gcc 和 clang 输出 42 42
,其他版本输出 0 0
。即使禁用优化。我会期望 42 1
。
编译器似乎假定 _Bool
只能是 1
或 0
,但同时它很乐意打印 42
在第一种情况下。
Q1:这是为什么?上面的代码是否包含未定义的行为?
Q2:sizeof(_Bool)
的可靠性如何? C17 6.5.3.4 根本没有提到 _Bool
。
最佳答案
Q1: Why is this? Does the above code contain undefined behavior?
是的,确实如此。该存储是有效的,但随后将其读取为 _Bool
则无效。
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.
它会可靠地告诉您存储一个 _Bool
所需的字节数。 6.5.3.4 也没有提到 int
,但你不是在问 sizeof(int)
是否可靠,是吗?
关于c - _Bool 类型和严格的别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52163870/