g++和gcc编译c程序结果不一样
就是下面的代码:
#include<stdio.h>
void swap(int *a, int *b)
{
*a ^= *b ^= *a ^= *b;
}
int main()
{
int a = 100, b = 1;
swap(&a, &b);
printf("%d %d\n", a, b);
return 0;
}
我使用gcc编译出来结果是0 100,
但是使用g++编译出来是1 100。
嗯,gcc版本gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 。。谢谢各位
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
可以参考C标准中关于sequence point的描述。
用gcc编译时加上警告选项-Wsequence-point,就比较明显了。
在C中,()、;、&&、||等等这样的地方是sequence-point。两个sequence-point之间的代码,编译器是可以任意优化的。也就是说,
*a ^= *b ^= *a ^= *b;
的计算顺序是未定义的。C++对sequence point的规定与C基本一致,
*a ^= *b ^= *a ^= *b;
的行为同样是未定义的。另外因为C++规定赋值语句的结果是左值,对这结果也可能会有影响。总之有side effect的写法还是尽量不要用。
第一 g++编译.c文件实际上也就是把c源文件当c++源文件编译。
第二 这段代码本来就是有歧义的,处理的顺序不同也就结果不同。编译器有时候特定的处理顺序经常会出现这种情况。
不过clang/clang++编译的结果都是 1 100
恭喜你,你触发了一个未定义行为!
swap函数中,符号执行的顺序是未定义的,不同编译器编译的结果会不一样。
可以看出gcc和g++编译出的汇编码是不一样的,两者中xor的应用对象不一样。
BTW,在异或交换之前,需要检查a和b是不是同一个对象,否则会产生糟糕的问题。