Lun*_*din 7 c boolean strict-aliasing language-lawyer c11
我正在尝试编写一些用于类型安全使用的宏_Bool,然后对我的代码进行压力测试.出于恶意测试的目的,我想出了这个肮脏的黑客:
_Bool b=0;
*(unsigned char*)&b = 42;
Run Code Online (Sandbox Code Playgroud)
鉴于实现上_Bool有1个字节sizeof(_Bool)==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;
}
Run Code Online (Sandbox Code Playgroud)
(代码依赖于printf隐式默认参数提升int)
某些版本的gcc和clang给出输出42 42,其他版本给出0 0.即使禁用了优化.我原以为是42 1.
似乎编译器假设_Bool只能是1或者0同时它42在第一种情况下快乐地打印.
Q1:这是为什么?上面的代码是否包含未定义的行为?
Q2:可靠性如何sizeof(_Bool)?C17 6.5.3.4完全没有提及_Bool.
小智 8
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)可靠,是吗?
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |