通过指针访问union成员(如下例所示)会导致C99中的未定义行为吗?意图似乎很清楚,但我知道有关于别名和联盟的一些限制.
union { int i; char c; } u;
int *ip = &u.i;
char *ic = &u.c;
*ip = 0;
*ic = 'a';
printf("%c\n", u.c);
Run Code Online (Sandbox Code Playgroud) 我发现这段代码使用“-fsanitize=undefined,address”和不使用它会产生不同的结果。
int printf(const char *, ...);
union {
long a;
short b;
int c;
} d;
int *e = &d.c;
int f, g;
long *h = &d.a;
int main() {
for (; f <= 0; f++) {
*h = g;
*e = 6;
}
printf("%d\n", d.b);
}
Run Code Online (Sandbox Code Playgroud)
命令行是:
$ clang -O0 -fsanitize=undefined,address a.c -o out0
$ clang -O1 -fsanitize=undefined,address a.c -o out1
$ clang -O1 a.c -o out11
$ ./out0
6
$ ./out1
6
$ ./out11
0
Run Code Online (Sandbox Code Playgroud)
Clang 版本是:
$ …Run Code Online (Sandbox Code Playgroud) 注意:学习严格的别名规则。请耐心等待。
代码示例(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;
}
Run Code Online (Sandbox Code Playgroud)
调用:
$ 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
Run Code Online (Sandbox Code Playgroud)
问题:将指向同一联合成员的两个指针传递给函数是否违反了严格的别名规则?
这个问题源于Unions 和 type-punning。
UPD20210901
如果在全局范围内定义联合类型会发生什么?
对于“u …