Vik*_*dav 5 c language-lawyer c11
以下代码段是C11标准§6.5.2.3中的示例:
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);
}
Run Code Online (Sandbox Code Playgroud)
根据C11,内部的最后一行g()无效.为什么这样?
该示例来自§6.5.2.3 结构和 ISO/IEC 9899:2011的联合成员中的示例3 .前面的一段是(重点补充):
6为了简化联合的使用,我们做了一个特殊的保证:如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查它们中任何一个的共同初始部分,可以看到完整类型的联合声明.如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享共同的初始序列.
问题中引用的代码前面是注释:
以下不是有效的片段(因为联合类型在函数中不可见
f).
根据突出的陈述,现在这是有道理的.代码中g()使用了公共的初始序列,但只适用于union可见且不可见的情况f().
这个问题也是严格的别名之一.这是一个复杂的话题.请参阅什么是严格别名规则?细节.
无论价值如何,即使在严格的警告选项下,GCC 7.1.0也不会报告问题.Clang也没有,即使有-Weverything选项:
clang -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
-Wstrict-prototypes -Weverything -pedantic …
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |