注意:学习严格的别名规则。请耐心等待。
代码示例(t935.c):
#include <stdio.h>
int f(int* pi, double* pd)
{
*pi = 13;
*pd = 7E-323;
return *pi;
}
int main(void)
{
union { int i; double d; } u;
printf("%d\n", f(&u.i, &u.d));
return 0;
}
调用:
$ gcc t935.c -Wall -Wextra -std=c11 -pedantic && ./a.exe
14
$ gcc t935.c -Wall -Wextra -std=c11 -pedantic -O2 && ./a.exe
13
$ gcc t935.c -Wall -Wextra -std=c11 -pedantic -O2 -fno-strict-aliasing && ./a.exe
14
问题:向函数传递两个指向同一联合成员的指针是否违反了严格的别名规则?
问题源自联合和类型双关 https://stackoverflow.com/questions/25664848/unions-and-type-punning.
UPD20210901
如果联合类型是在全局范围内定义的,会发生什么?
对于“联盟u
是在全局范围内定义的”(实际上file范围)情况 gcc 和 clang 都显示与上面报告的 gcc 相同的结果。
这是C标准的一个缺陷。看缺陷报告 236 http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm.
6.5 7 中的别名规则旨在允许编译器假定指向不满足该规则的两种类型的指针引用“不同”对象,但该规则无法充分提供联合成员(而且,根据缺陷报告,动态分配内存中的对象)。获取两个联合成员的地址可能会产生指向两种类型的指针,这两种类型根据别名规则可能不会别名,但引用相同的内存。因此,C标准在这方面被破坏了,并且C委员会还没有纠正这个问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)