C++ union 的未定义行为

标签 c++

只是阅读了一些匿名结构以及它是如何不标准的以及它的一些一般用例是未定义的行为...

这是基本情况:

struct Point {
    union {
       struct {
           float x, y;
       };
       float v[2];
    };
};

因此写入 x 然后从 v[0] 读取将是未定义的,因为您希望它们相同,但事实可能并非如此。

不确定这是否在标准中但属于同一类型...

union{ float 一个; float b; };

写入a然后从b读取是否未定义?

也就是说,标准是否说明了数组和相同类型的顺序变量的二进制表示。

最佳答案

标准说从 union 其他元素中的任何元素读取 比最后一个写的是未定义的行为。从理论上讲, 编译器可以生成以某种方式跟踪的代码 读取和写入,并触发一个信号,如果你违反了 规则(即使两者是同一类型)。编译器也可以 使用事实进行某种优化:如果您写入 a (或 x),它可以假定您不阅读 b(或 v[0]) 优化时。

实际上,我知道的每个编译器都支持这个,如果 union 清晰可见,并且在很多(大多数?,全部?) 如果 union 不可见,即使合法使用也会失败 (例如:

union  U { int i; float f; };

int f( int* pi, int* pf ) { int r = *pi; *pf = 3.14159; return r; }

//  ...
U u;
u.i = 1;
std::cout << f( &u.i, &u.f );

我实际上已经看到 g++ 失败了,尽管根据 标准,这是完全合法的。)

此外,即使编译器支持写入 Point::x 和 从 Point::v[0] 读取,不能保证 Point::yPoint::v[1] 甚至具有相同的物理地址。

关于C++ union 的未定义行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17273320/

相关文章:

c++ - 将一条线从2个点延长到一定长度

c++ - top 如何查看内存使用情况

c++ - 所有模板参数包的默认值都是 "empty"吗?

c++ - 三次方贝塞尔曲线到二次方

c++ - 多个静态类成员函数都具有相同的参数并返回

c++ - 使用 std::filesystem 输出作为 LPCWSTR

c++ - 从构建库切换到 exe 或 dll 时出现 Unresolved external symbol 错误

c++ - 什么时候我们需要提供模板参数来定义一个类?

c++ - 编译 Eigen 程序时出错 : error: 'seq' is not a member of 'Eigen'

c++ - long long 到 long double 的转换