4

我在 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");
}

在此代码的更复杂版本(显示完全相同的问题)中,我将以下运算符用于封装 std::vector 作为传递的类 RealVector

inline double & operator[] (int index) { return data_[index]; }

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

它是编译器错误,还是发生了一些微妙的魔法?我尝试检查 asm 和解析树,但它太复杂而无法理解。我通常使用 C 进行管理,但在 C++ 中,生成的文件中有太多的黑魔法。

4

1 回答 1

8

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

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

于 2013-11-15T08:39:52.473 回答