由于在C++ std :: vector中使用内联函数而使用g ++ 4.4.7 20120313(32位)导致精度变化

Ste*_*ini 4 c++ gcc g++

我正在编译centos5.9 32位(在64位机器上运行),目标是32位.g ++版本是4.4.7,它不是默认情况下在centos5.9上提供的版本,但它可以与yum一起下载并作为发行版的一部分提供.

我有一个非常简单的循环如下

std::vector<double> result(n);
std::vector<double> values(n);
// here I compute values(). They are correct and I extensively noted 
// that there's nothing wrong there. The problem is here
result[0] = 0.0;
for ( int i = 0 ; i < n-1 ; ++i ) {
    result[i+1] = result[i]+values[i];
    // printf("x");
}
Run Code Online (Sandbox Code Playgroud)

在这个代码的一个更复杂的版本(显示完全相同的问题)中,我使用以下运算符为类的RealVector封装std :: vector作为passthrough

inline double & operator[] (int index) { return data_[index]; }
Run Code Online (Sandbox Code Playgroud)

问题是我在结果中发现了一个微小但相关的数值差异,这取决于运算符[]是否内联.同样,如果我取消注释上面给出的printf()行,我也会更改结果.请注意,在具有相同配置的centos59 64位中不会出现此问题,或者如果它出现,则低于可检测性.

它是一个编译器错误,还是有一些微妙的魔法?我试图检查asm和解析树,但它太复杂了,无法理解.我通常使用C管理,但在C++中,生成的文件中会出现太多黑暗魔法.

MSa*_*ers 8

可能是旧的x87有趣的功能,80位寄存器.将该寄存器溢出到内存会导致四舍五入到64位,并且会在不可预测的时刻发生.完全不是C++独有的,C也有同样的问题.在Java中它是"复杂的"

通过移动到64位构建和SSE来修复.