变量优化为零

时间:2013-04-30 02:58:56

标签: c++ g++

在以下程序中,如果使用out以上的优化编译0变量,O1变量始终打印为out。如果我取消注释cout函数中的digitTruncate行,则#include <iostream> #include "mytime.hpp" #include <stdint.h> template <class IN> int32_t digitTruncate (IN data_in, uint32_t digits, uint64_t* data_out, int32_t bits = -1, bool safe = false) { if (bits == -1) bits = (digits / 0.3010299957) + 1; if (!safe) { if (bits > (int32_t)sizeof(data_in) * 8) return -1; } *data_out = (data_in & (0xffffffffffffffff >> (64 - bits))); //std::cout << *data_out << std::endl; return (bits / 8) + 1; } int main() { uint64_t cycles1, cycles2; uint32_t out; char* block = new char[8]; cycles1 = mytime::cycles(); for (int i = 0; i < 10000; i++) { uint32_t init = (uint32_t)mytime::cycles(); digitTruncate(init, 5, ((uint64_t*)block), 17, true); out = *((uint32_t*)block); } cycles2 = mytime::cycles(); std::cout << cycles2 - cycles1 << std::endl; std::cout << "results: " << out << std::endl; return 0; } 变量可以使用任何优化级别正确打印。

我做的是“未定义”的事情,还是编译问题?

{{1}}

2 个答案:

答案 0 :(得分:3)

通过访问block作为指向uint64_tuint32_t的指针,您违反了严格的别名规则。允许编译器假定特定地址仅作为char*和另一种类型被访问(别名)。您正在使用两个非char*类型,因此关于编译器的优化器将执行的操作,所有投注均已关闭。

答案 1 :(得分:1)

由于循环中out的值已经死亡,除了最后一次迭代,并且除了设置block(因此out)之外,该函数没有副作用,编译器可以自由地消除循环,并只评估最后一次迭代。来自最后一次迭代的大部分代码也可以不断折叠起来。

所以你最终只能连续两次调用mytime::cycles(),这可能会有0 ...

编译器可能首先内联调用,然后将其简化为无,而不是注意到它实际上没有做任何事情,但整体效果是一样的。