接前面C/Cpp strict alias小结,看一些与此相关的例子:
例子一
测试环境:gcc-4.4(ubuntu x86),gcc-4.4(mingw32)
结果:
| 编译用命令及选项 | 结果 |
| gcc -Wall hello.c | 0 |
| gcc -Wall -O3 hello.c | 1 |
代码:
#include <stdio.h>
int 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 |
代码:
#include <stdio.h>
int 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在这儿弄错了,简化得太厉害了?)
测试环境:
- gcc4.4/4.5(Ubuntu X86)
- gcc4.4(mingw32)
- visual studio 2010, X86
- clang 2.8 (Ubuntu X86)
- Sun studio 11 (X4100/Solaris,x86)
- gcc3.4 (X4100/Solaris,x86)
- Sun studio 11 (T1000/Solaris,Sparc)
- gcc4.0 (T1000/Solaris,Sparc)
结果(只看到大小端的区别):
| T1000/Solaris,Sparc | 65578 | 大端 |
| 其他平台 | 1 | 小端 |
代码:
#include <stdio.h>
int 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中说:
- The following code can cause an aliasing problem:
i = -100; while( i < 0 ) { i += x + y; *p = i; }
不过,这个和 strict alias 应该没多少关系。
92

被折叠的 条评论
为什么被折叠?



