在工会之间传递价值的正确方法是什么?

时间:2018-04-21 16:08:40

标签: c language-lawyer unions

如果你有:

/var/www

如果你知道a的类型,你应该

typedef union value {
    int i;
    float f;
} VALUE;
VALUE a, b;

b.i = a.i;
b.f = a.f;

3 个答案:

答案 0 :(得分:6)

只要使用b = a,除非有特殊原因,例如联盟偶尔会包含大量数据,并且您希望在仅包含少量数据的情况下优化分配。< / p>

Per C 2011 [N1570] 6.5.16.1 1,简单分配的可接受情况之一是:

  

左操作数具有与右侧类型兼容的结构或联合类型的原子,限定或非限定版本。

按6.2.7 1:

  

如果类型相同,则两种类型具有兼容类型。

(根据6.2.6.1 6,“结构或联合对象的值永远不是陷阱表示,即使结构或联合对象的成员的值可能是陷阱表示。”)

答案 1 :(得分:1)

最正确的可能是(假设相同的类型)

memcpy(&b, &a, sizeof(b));

答案 2 :(得分:0)

标准没有规定在什么情况下可以通过非字符类型的成员访问左值访问与聚合关联的存储。如果联合成员member1是联合中的最大类型并且没有陷阱表示,那么质量编译器应该能够处理诸如

之类的操作
objectOfMemberType = someUnion.member1;
someUnion.member1 = valueOfMemberType;

质量编译器对于像

这样的结构也应该没有问题
memberType *p = &someUnion.member1;
*p = valueOfMemberType;

编写标准时,如果成员属于非字符类型,它对任一构造的行为都没有要求,因此在不调用UB的情况下对联合做任何事情的唯一方法是使用联合类型的左值要复制union的全部内容,请使用字符类型的左值来访问union的各个部分,或者使用memcpy之类的函数。直接通过成员左值访问联合内容在gcc和clang中似乎最可靠(我认为我发现它不是无意的错误的情况)但gcc和clang似乎都没有设计为可靠地支持任何使用union成员指针,即使使用立即跟随取得地址的行为[如上所示]。

考虑到C标准的编写方式,很难真正确定在工会之间传递值的“正确”方式,因为以有用的方式使用联合的大多数代码会调用UB。哪种方法最好取决于哪种形式的UB愿意相信一个人的编译器能够合理地处理。