_Bool 类型和严格别名 [英] _Bool type and strict aliasing

查看:17
本文介绍了_Bool 类型和严格别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写一些宏以安全地使用 _Bool,然后对我的代码进行压力测试.为了邪恶的测试目的,我想出了这个肮脏的黑客:

_Bool b=0;*(无符号字符*)&b = 42;

鉴于 _Bool 在实现 sizeof(_Bool)==1) 上是 1 个字节,我看不出这种 hack 是如何违反 C 标准的.这不应该是严格的别名违规.

然而,当通过各种编译器运行这个程序时,我遇到了问题:

#include <stdio.h>诠释主要(无效){_Static_assert(sizeof(_Bool)==1, "_Bool 不是 1 字节");_Bool b=0;*(无符号字符*)&b = 42;printf("%d", b);printf("%d", b!=0 );返回0;}

(代码依赖于printf隐式默认参数提升到int)

某些版本的 gcc 和 clang 给出输出 42 42,其他版本给出 0 0.即使禁用了优化.我会期待 42 1.

编译器似乎假设 _Bool 只能是 10,但同时它会愉快地打印 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)是否可靠,是吗?

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 assume 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.

解决方案

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?

这篇关于_Bool 类型和严格别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆