C ++具有联合的未定义行为 [英] C++ Undefined behaviour with unions

查看:230
本文介绍了C ++具有联合的未定义行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Was just reading about some anonymous structures and how it is isn't standard and some general use case for it is undefined behaviour...

这是基本的case:

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

因此写入x然后从v [0]读取将是未定义的,

So writing to x and then reading from v[0] would be undefined in that you would expect them to be the same but it may not be so.

不知道这是否在标准中,但是同一类型的工会...

Not sure if this is in the standard but unions of the same type...

union {float a;浮动b };

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

Is it undefined to write to a and then read from b ?

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

That is to say does the standard say anything about binary representation of arrays and sequential variables of the same type.

推荐答案

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

The standard says that reading from any element in a union other than the last one written is undefined behavior. In theory, the compiler could generate code which somehow kept track of the reads and writes, and triggered a signal if you violated the rule (even if the two are the same type). A compiler could also use the fact for some sort of optimization: if you write to a (or x), it can assume that you do not read b (or v[0]) when optimizing.

实际上,我知道的每个编译器都支持这一点,如果 union
清晰可见,有很多情况下(大多数?,所有?)
其中即使合法使用将失败如果联合不可见
(例如:

In practice, every compiler I know supports this, if the union is clearly visible, and there are cases in many (most?, all?) where even legal use will fail if the union is not visible (e.g.:

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 ++看到了这个失败, )

I've actually seen this fail with g++, although according to the standard, it is perfectly legal.)

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

Also, even if the compiler supports writing to Point::x and reading from Point::v[0], there's no guarantee that Point::y and Point::v[1] even have the same physical address.

这篇关于C ++具有联合的未定义行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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