I am compiling on centos5.9 32 bit (running on a 64 bit machine), targeting 32 bits. g++ version is 4.4.7, which is not the one shipped by default on centos5.9, but it can be downloaded with yum and is provided as part of the distro.
I have a very simple loop as follows
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");
}
In a more complicated version of this code (which shows the exact same problem) I used the following operator for a class RealVector encapsulating a std::vector as a passthrough
inline double & operator[] (int index) { return data_[index]; }
The problem is that I found a tiny but relevant numerical difference in the result, depending if the operator[] is inline or not. Similarly, I also change the result if I uncomment the printf() line given above. Note that the problem does not occur in a centos59 64 bit with the same configuration, or if it occurs, it's below detectability.
Is it a compiler bug, or there's some subtle magic going on? I tried to check both the asm and the parse tree, but it's too complex to understand. I generally manage with C, but in C++ there's too much dark magic going on in the resulting files.
Probably the old x87 fun feature again, 80 bits registers. Spilling that register to memory causes a rounding to 64 bits, and happens at unpredictable moments. Not at all unique to C++, C has the same issue. In Java it's "complicated"
Fixed by moving to 64 bit builds and SSE.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With