ngo%tammy@HARVARD.HARVARD.EDU (Tom Ngo) (02/10/90)
g++ : 1.36.4
Machine : Convex C220
The following program exercises a stripped-down class of
3-vectors. The important lines are
nx = Vec(7000,8000,9000);
ny = nx + nx;
One expects the final value of ny to be (14000,16000,18000)... but
when -O is used, it is (14000,40,18000). The 40 comes from the
assignment x[1]=20 from the initialization of x.
The bug depends on everything upstream of the two lines that I
called important. I have chosen initial values for the vectors
that help track where later values come from.
If x is accessed prior to "ny = nx + nx" (as in cout << "x "), the
bug goes away.
--Tom Ngo
ngo@harvard.edu
=== bug.cc (25 lines) =================================================
#include <stream.h>
class Vec {
public:
int n[3];
Vec(int x,int y,int z) { n[0]=x; n[1]=y; n[2]=z; }
~Vec() {}
Vec(const Vec& that) { *this = that; }
Vec& operator = (const Vec& that) {
n[0] = that.n[0]; n[1] = that.n[1]; n[2] = that.n[2]; }
friend Vec operator + (const Vec& a, const Vec& b)
{ return Vec( a.n[0]+b.n[0], a.n[1]+b.n[1], a.n[2]+b.n[2] ); }
};
main()
{
Vec nx(10,20,30);
Vec nz(400,500,600);
Vec ny(0,0,0);
ny = nz + nx; // Final value of ny never shows any nz
nx = Vec(7000,8000,9000); // nx[1]=8000 appears to get optimized out
ny = nx + nx; // Interchange with next line to remove diffs
cout << "x " << nx.n[0] << " " << nx.n[1] << " " << nx.n[2] << "\n";
cout << "y " << ny.n[0] << " " << ny.n[1] << " " << ny.n[2] << "\n";
}
=== Makefile (7 lines) ====================================================
test: opt nopt
nopt
opt
opt: bug.cc
g++ -g -O bug.cc -lm -o opt
nopt: bug.cc
g++ -g bug.cc -lm -o nopt
===========================================================================