繁体   English   中英

C标准对两种相同类型的联合说了什么

[英]What does C standard say about a union of two identical types

是否有可能在任何架构上使用任何编译器使以下断言失败?

union { int x; int y; } u;
u.x = 19;
assert(u.x == u.y);

C99对一个联合的两个成员是共享初始字段序列的结构的情况做出特殊保证:

struct X {int a; /* other fields may follow */ };
struct Y {int a; /* other fields may follow */ };
union {X x; Y y;} u;
u.x.a = 19;
assert(u.x.a == u.y.a); // Guaranteed never to fail by 6.5.2.3-5.

6.5.2.3-5:为了简化联合的使用,我们做了一个特殊的保证:如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,那么允许在任何可以看到完整类型的联合声明的地方检查其中任何一个的共同初始部分。 如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享共同的初始序列。

但是,我无法为联盟内的非结构化类型找到可比较的保证。 但这很可能是一个遗漏:如果标准花了一些长度来描述结构类型必然会发生什么,甚至不相同,它应该澄清更简单的非结构化类型的相同点。

问题中的assert永远不会在标准C的实现中失败,因为在分配给ux之后访问uy需要将ux的字节重新解释为uy的类型。 由于类型相同,重新解释产生相同的值。

该要求在C 2011(N1570)6.5.2.3注释95中注明,其表示它源自第6.2.6节,其涵盖了类型的表示。 注95说:

如果用于读取union对象内容的成员与上次用于在对象中存储值的成员不同,则将值的对象表示的相应部分重新解释为新类型中的对象表示形式在6.2.6中描述(一个过程有时被称为''punning'')。 这可能是陷阱表示。

(N1570是一份非正式的草案,但很容易上网 。)

我相信这个问题很难以您期望的方式回答。

据我所知,读取一个不是最近写入的union一个字段,是未定义的行为。

因此,用“否”回答是不可能的,因为任何编译器编写者都可以自由地专门检测到这一点,并且如果他们有这种感觉就会让它失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM