_Bool类型和严格别名
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了_Bool类型和严格别名相关的知识,希望对你有一定的参考价值。
我试图编写一些宏来安全地使用_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:这是为什么?上面的代码是否包含未定义的行为?
是的,它确实。商店是有效的,但后来读作_Bool
不是。
6.2.6类型的表示
6.2.6.1总则
5某些对象表示不需要表示对象类型的值。如果对象的存储值具有这样的表示并且由不具有字符类型的左值表达式读取,则行为是未定义的。 [...]
Q2:
sizeof(_Bool)
有多可靠? C17 6.5.3.4根本没有提到_Bool
。
它将可靠地告诉您存储一个_Bool
所需的字节数。 6.5.3.4也没有提到int
,但你不是在问sizeof(int)
是否可靠,是吗?
以上是关于_Bool类型和严格别名的主要内容,如果未能解决你的问题,请参考以下文章