视觉C++ 2017 错误?编译器优化表达式
Visual C++ 2017 bug? Compiler optimizes away expression
以下一段代码给我带来了一些问题,特别是diff的评估:
#include <iostream>
template<typename T>
class array2d
{
protected:
T* arr;
int w, h;
public:
array2d() : arr(nullptr), w(0), h(0) {}
bool init(int w, int h)
{
free();
arr = new (std::nothrow) T[w*h];
if (arr == nullptr)
{
std::cerr << "array2d::init(): Failed to allocate: " << w * h * sizeof(T) << " bytes.n";
return false;
}
this->w = w;
this->h = h;
return true;
}
void fill(T v)
{
for (int i = 0; i < w*h; ++i)
arr[i] = v;
}
void free()
{
if (arr != nullptr)
{
delete[] arr;
arr = nullptr;
w = 0;
h = 0;
}
}
template<typename U>
bool copy(const array2d<U>& v)
{
if (!v)
{
std::cerr << "array2d::copy(): Input array is empty.n";
return false;
}
if (w*h != v.width()*v.height())
{
if (!init(v.width(), v.height())) return false;
}
for (int i = 0; i < w*h; ++i)
arr[i] = static_cast<T>(v(i));
return true;
}
inline T operator()(int i) const { return arr[i]; }
inline T& operator()(int i) { return arr[i]; }
inline T operator[](int i) const { return arr[i]; }
inline T& operator[](int i) { return arr[i]; }
inline T operator()(int x, int y) const { return arr[x + y*w]; }
inline T& operator()(int x, int y) { return arr[x + y*w]; }
inline int width() const { return w; }
inline int height() const { return h; }
inline const T* get() const { return arr; }
inline T* get() { return arr; }
operator bool() const { return arr != nullptr; }
array2d<T>& operator*=(T v)
{
for (int i = 0; i < w*h; ++i)
arr[i] *= v;
return *this;
}
~array2d() { free(); }
};
typedef unsigned long long uint64;
uint64 computeErrors(const array2d<uint64>& a, const array2d<uint64>& b)
{
uint64 MNE = 0;
for (int i = 0; i < a.height()*a.width(); ++i)
{
uint64 diff = ((a[i] >= b[i]) ? a[i] - b[i] : b[i] - a[i]);
if (a[i] != b[i])
{
std::cout << "Diff: " << diff << "n";
std::cout << "What diff should equal to: " << ((a[i] >= b[i]) ? a[i] - b[i] : b[i] - a[i]) << "n";
}
if (i == 0)
{
std::cout << "Diff should not be 0, but it is: " << diff << "n";
}
if (MNE < diff)
{
MNE = diff;
std::cout << "We should reach this, but we don't.n";
}
}
return MNE;
}
int main()
{
int w = 1;
int h = 1;
array2d<uint64> a;
if (!a.init(w,h)) return 1;
a.fill(0);
array2d<uint64> b;
if (!b.init(w,h)) return 1;
b.fill(0);
a[0] = 0ull;
b[0] = 1;
std::cout << a[0] << " " << b[0] << "n";
auto e = computeErrors(a, b);
std::cout << "MNE: " << e << "n";
return 0;
}
如果我用/O1、/O2 或/Ox;用/Ot 和/Ob2 编译它,那么 diff 总是 0,而它不应该是。如果我在没有/Ot 或没有/Ob2 的情况下编译,一切都按预期工作。此代码中是否有任何格式不正确的内容?我在这里附上了整个事情:http://coliru.stacked-crooked.com/a/245f23f05df39418。但是,如果我更改数组的 [] 运算符以返回 const T&而不是 T,则一切正常。这是编译器错误吗?还是我在运算符中返回 T 而不是 const T&不好(我返回 T,因为我在某处读到按值传递较小的 POD 更快,就我而言,我有一些带有 uint32 的数组,其中速度非常重要(。我目前正在使用 Visual C++ 2017。
编辑:根据user4581301的建议,我也在这里添加了整个代码。
编辑2:这是我_MSC_FULL_VER:191125547。
该报告于2018年2月28日提交给Visual Studio Developer Community(我假设是@lightxbulb(。
2018 年 5 月 8 日,据报道(同一链接(该问题已在最新的 Visual Studio 版本中解决,即 2017 15.7(根据帖子标题中的信息(。
相关文章:
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- VS2017调试器:没有地址,可能是由于编译器优化
- 何时允许编译器优化复制构造函数
- 如何使用 GCC 编译器优化创建静态库?
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 是否允许编译器优化掉局部易失性变量
- 删除编译器优化并在发布中启用 pdb 文件
- 静态 constexpr 的编译器优化
- 如何让MSVC编译器优化多步POD初始化?
- 按位不操作的编译器优化
- 模板专用化与编译器优化
- 编译器优化:G 比英特尔慢
- 运算符重载关联性编译器优化
- Intel OpenCL编译器:优化结构使用情况
- C 中编译器优化的影响
- 视觉C++ 2017 错误?编译器优化表达式
- 虚拟功能编译器优化C
- 未定义的行为确实有助于现代编译器优化生成的代码