变量优化为零
Variable optimized to zero
在下面的程序中,如果在O1
以上进行优化编译,则out
变量始终打印为0
。如果我取消digitTruncate
函数中的cout
行注释,那么out
变量在任何优化级别下都可以正确打印。
我正在做的事情是"未定义",还是这是一个编译器问题?
#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;
}
通过访问block
作为指向uint64_t
和uint32_t
的指针,您违反了严格的别名规则。编译器可以假设一个特定的地址只被char*
和另一种类型访问(别名)。您正在使用两种非char*
类型,因此所有的赌注都是关于编译器的优化器将做什么。
由于循环中的out
的值是死的,除了最后一次迭代之外,并且该函数除了设置block
(以及out
)之外没有任何副作用,编译器可以自由地消除循环,只计算最后一次迭代。最后一次迭代的大部分代码也可以被固定地折叠起来。
所以你最终只连续两次调用mytime::cycles()
,这可能有0的差异…
编译器可能首先将调用内联,然后将其简化为什么都不做,而不是注意到它实际上什么都不做,但总体效果是一样的。
相关文章:
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- C++编译器是否优化了顺序静态变量读取?
- 当空基类也是成员变量时,为什么禁止空基优化?
- 未使用的C++未优化的静态成员函数/变量
- C++将 lambda 函数另存为成员变量,而不使用函数指针进行优化
- 未能优化看似明显的循环不变量(但volatile限定符发挥了神奇的作用)
- 现代c++编译器会优化不可变的临时变量吗
- 是否允许编译器优化掉局部易失性变量
- 现代编译器会优化只引用对象子集的局部变量吗
- 优化堆上创建的冗余变量
- 局部堆栈变量成员的返回值优化
- 为什么编译器并不总是优化局部变量?
- 静态局部变量会被错误地优化吗?
- 优化易失变量
- 关于循环变量优化的标准合规行为是什么?
- 用于 C/C++ 中的循环变量优化
- 为什么C++编译器不优化对结构数据成员的读取和写入,而不是不同的局部变量?
- 优化成员变量访问
- 如何查看C++中<优化>变量的值?
- c++:避免优化变量