将指向同一联合成员​​的两个指针传递给函数是否违反严格的别名规则?

Does passing to a function two pointers pointed to members of the same union violate the strict aliasing rule?

注意:学习严格的别名规则。请耐心等待。

代码示例(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

问题:向函数传递两个指向同一联合成员​​的指针是否违反严格的别名规则?

问题来自Unions and type-punning

UPD20210901

what would happen if the union type was defined at global scope?

对于“union u is defined at global scope”(实际上是 file 范围),gcc 和 clang 显示的结果与上面报告的 gcc 相同。

这是 C 标准中的缺陷。参见 Defect Report 236

6.5 7 中的别名规则旨在允许编译器假定指向不满足规则的两种类型的指针引用“不同”对象,但该规则未能充分提供联合成员(以及,根据缺陷报告,动态分配内存中的对象)。获取两个联合成员的地址可能会产生指向两种类型的指针,这两种类型根据别名规则可能不会别名,但引用同一内存。因此,C标准在这方面被打破了,C委员会也没有纠正这个问题。