【发布时间】:2015-11-04 16:10:22
【问题描述】:
我们刚从 VS2010 迁移到 VS2013,我发现了一个奇怪的错误,我想这可能是编译器的原因。
使用命令行cl ConsoleApplication1.cpp /EHa /fp:strict /O2 编译,以下程序给出:
0xC0000005: Access violation reading location 0xFFFFFFFF.
这仅在编译为 32 位(不是 64 位)时发生
#include <iostream>
#include <cmath>
class Vector2D
{
public:
double x;
double y;
Vector2D() : x(0), y(0) {}
Vector2D(double _x, double _y) : x(_x), y(_y) {}
double Width() { return x; }
double Height() { return y; }
};
bool IsEqual(const double & a, const double & b)
{
if (a == b)
return true;
double tolerance = pow(10., -5);
if (::fabs(a) < tolerance / 2.)
{
return ::fabs(b) < tolerance / 2.;
}
double diff = ::fabs((b - a) / a);
return (diff < tolerance);
}
bool IsEqual(Vector2D & a, Vector2D & b)
{
return IsEqual(a.Width(), b.Width()) && IsEqual(a.Height(), b.Height());
}
std::string GetMsg()
{
return std::string("");
}
int main(int argc, char* argv[])
{
Vector2D v1;
Vector2D v2;
v1 = Vector2D(1, 0);
// This innocent call will cause an access violation
// the access violation occurs *only* if fp:strict and /EHa switches are used
GetMsg(), IsEqual(v1, v2);
return 0;
}
我是在指责编译器快吗?
【问题讨论】:
-
代码在我看来很好。我会选择编译器错误。继续删除位以最小化您的代码,并报告错误。您可能会从
foo和height中删除字符串,并稍微简化IsEqual。 -
""绑定到std::string&是未定义的行为,删除该位并确认错误仍然存在 -
@MooingDuck 问题依旧
-
不,不要停止调用height和width,只删除一个。你可能只需要一个来复制。这会重现吗? ideone.com/qhum2q 尝试找出Minimal Verifiable Example。
-
这个 bug 出现在 VS2013 而不是 VS2015。
标签: c++ visual-studio floating-point compiler-bug msvc12