【发布时间】:2018-09-12 08:11:22
【问题描述】:
以下不是现代 C 中未定义的行为:
union foo
{
int i;
float f;
};
union foo bar;
bar.f = 1.0f;
printf("%08x\n", bar.i);
并打印 1.0f 的十六进制表示。
但以下是未定义的行为:
int x;
printf("%08x\n", x);
这个呢?
union xyzzy
{
char c;
int i;
};
union xyzzy plugh;
这应该是未定义的行为,因为尚未写入 plugh 的任何成员。
printf("%08x\n", plugh.i);
但是这个呢。这是未定义的行为吗?
plugh.c = 'A';
printf("%08x\n", plugh.i);
现在大多数 C 编译器都有sizeof(char) < sizeof(int),sizeof(int) 是 2 或 4。这意味着在这些情况下,最多 50% 或 25% 的 plugh.i 将被写入,但读取剩余的字节将读取未初始化的数据,因此应该是未定义的行为。在此基础上,是不是整个读取未定义行为?
【问题讨论】:
-
@Tom's - 访问不确定值是 UB。点空白。
-
@Tom's 那行没有强制转换,为什么你认为使用未初始化的变量不是 UB?
-
@Tom's - “但它永远不会崩溃,但行为不同” 这里的主题是 C 标准,它不保证任何类型的东西。这就是未定义行为的全部意义所在。
-
@Tom's A cast 是一种显式类型转换。这里没有演员。甚至没有隐式转换,因为 varargs 没有为您提供已知的类型上下文。还是您认为
printf("%f", 42)可以,因为42可以隐式转换为double? -
@Stargateur 通过联合的类型双关语在 C 中得到了很好的定义,尽管我只会在 C++ 中使用 memcpy 和 bit_cast 请参阅 my answer here for more details。我个人feel that unions are meant for variant types 但那艘船很久以前就离开了。
标签: c language-lawyer undefined-behavior unions type-punning