以下示例在C11标准6.5.2.3中给出
以下不是有效的片段(因为在函数f中看不到联合类型):
struct t1 { int m; }; struct t2 { int m; }; int f(struct t1 *p1, struct t2 *p2) { if (p1->m < 0) p2->m = -p2->m; return p1->m; } int g() { union { struct t1 s1; struct t2 s2; } u; /* ... */ return f(&u.s1, &u.s2); }
为什么对函数f可见联合类型很重要?
在仔细阅读了相关部分几次后,我在包含部分中看不到任何不允许这样做的内容。
这很重要,因为有6.5.2.3第6段(添加了重点):
为了简化并集的使用,做出了一项特殊保证:如果并集包含多个具有共同初始序列的结构(请参见下文),并且如果并集对象当前包含这些结构之一,则可以检查该并集。在联合的完整类型的声明可见的任何地方的初始部分。如果相应成员对一个或多个初始成员的序列具有兼容的类型(对于位域,则具有相同的宽度),则两个结构共享一个公共的初始序列。
这不是需要诊断的错误(语法错误或约束冲突),但行为未定义,因为和对象的m
成员占用相同的存储空间,但是由于和是不同类型,允许编译器假定它们没有相同的行为。 t-特别是对的更改不会影响的值。例如,编译器可以在第一次访问时将in的值保存在寄存器中,然后在第二次访问时不从内存中重新加载它的值。struct t1
struct t2
struct t1
struct t2
p1->m
p2->m
p1->m
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句