Leo*_*nid 8 c++ 64-bit gcc strict-aliasing compiler-optimization
没有-O2这个代码打印84 84,输出为O2标志84 42.代码是gcc 4.4.3.在64位Linux平台上编译的.为什么以下代码的输出不同?
请注意,使用-Os编译时输出为 0 42
#include <iostream>
using namespace std;
int main() {
long long n = 42;
int *p = (int *)&n;
*p <<= 1;
cout << *p << " " << n << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
CB *_*ley 19
当您使用gcc进行优化时,它可以根据表达式的类型使用某些假设,以避免重复不必要的读取并允许在内存中保留变量.
您的代码具有未定义的行为,因为您将一个指针long long(一个gcc允许作为一个扩展)转换为指向一个指针int,然后操纵指向对象,就像它是一个int.指针指向int通常不能指向类型的对象,long long因此允许gcc假定写入int(通过指针)的操作不会影响具有类型的对象long long.
因此,n在它最初分配的时间和随后打印的时间之间缓存值是合法的.没有有效的写操作可能会改变其值.
要阅读的特定开关和文档是-fstrict-aliasing.
你正在打破严格的别名.用-Wall编译会给你一个dereferencing type-punned pointer警告.参见例如http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
| 归档时间: |
|
| 查看次数: |
386 次 |
| 最近记录: |