接前面C/Cpp strict alias小结,看一些与此相关的例子:
测试环境:gcc-4.4(ubuntu x86),gcc-4.4(mingw32)
结果:
编译用命令及选项 |
结果 |
gcc -Wall hello.c |
0 |
gcc -Wall -O3 hello.c |
1 |
代码:
#includeint a; int f(float *b) { a = 1; *b = 0; return a; } int main() { printf("%d\n", f((float*)&a)); return 0; }
测试环境:gcc-4.4/4.5(ubuntu x86),gcc-4.4(mingw32)
编译用命令及选项 |
结果 |
gcc -Wall hello.c |
65535 |
gcc -Wall -O3 hello.c |
42 |
代码:
#includeint main() { void *buf[4]; int *i = (int *) buf; short *s = (short *) buf; *i = 42; s[0] = 0; s[1] = 1; printf("%d\n", *i); return 0; }
按照我们在上一篇提到的内容,这个例子的结果在C语言中应该是可预知的(由实现定义?),而在C++中的行为可能是未定义的。
而type-punning-and-strict-aliasing一文中,提到:这个例子的结果在gcc下面是1,在其他编译器下则不尽然。(我尝试重现这个东西,却总是不成功,估计是Thiago在这儿弄错了,简化得太厉害了?)
测试环境:
结果(只看到大小端的区别):
T1000/Solaris,Sparc |
65578 |
大端 |
其他平台 |
1 |
小端 |
代码:
#includeint main() { union { int i; short s; } u; u.i = 42; u.s = 1; printf("%d\n", u.i); return 0; }
(Ab)Use of the ANSI C aliasing rules给出这样一段代码:
/*alias.c*/ int foo(char *c) { char a[100]; char *cptr = a; *(int *)cptr = *(int*)c; return 0; }
使用IBM的 xlc 编译器
xlc -c alias.c -O3 -qlist=./ -qflag=i -qinfo
可以看到如下警告信息
INFORMATIONAL CCN3495 ./alias.c:5 Pointer type conversion found. INFORMATIONAL CCN3374 ./alias.c:5 Pointer types "int*" and "char*" are not compatible. INFORMATIONAL CCN3495 ./alias.c:5 Pointer type conversion found. INFORMATIONAL CCN3374 ./alias.c:5 Pointer types "int*" and "char*" are not compatible. INFORMATIONAL CCN3415 ./alias.c:7 The external function definition "foo" is never referenced.
没有这种环境,无法测试,而且http://www.unix-center.net提供的 IBM UNIX eServer p510 服务最近无法登录。
Visual Studio .NET 2003 存在 /Oa 和 /Ow 两个和 alias 有关的优化选项,不过从 VS2005 开始,似乎这两个选项消失了。
MSDN VS2003中说:
i = -100; while( i < 0 ) { i += x + y; *p = i; }
不过,这个和 strict alias 应该没多少关系。