T.Day@ucl-cs.UUCP (12/19/89)
From: Tim Day <T.Day@uk.ac.ucl.cs> +-----------------------------------------------------------------------------+ Tim Day | Meet every second in life as challenge; Department of Photogrammetry | Respond fully to whatever happens UCL, Gower St., London WC1E 6BT | without anxiety, or complaint, or clinging +-----------------------------------------------------------------------------+ // Hope you can handle this... I like it W I D E // // I recently got around to putting some consts in my Vector3 class // .. which promply broke. This used to work fine before // I added the consts. Am I using them right ? I get no errors from compiler // // Compiled with g++ (-v gcc version 1.36.1 (based on GCC 1.36)) on Sun3, OS4.something>0 // g++ -m68020 -m68881 -O -fdefault-inline -finline-functions -fstrength-reduce -fomit-frame-pointer vector.cc -o vector // Problem described in main() at end // g++ -m68020 -m68881 -g vector.cc -o vector works OK... some kinda optimisation bug // Also works fine if you #define const /* */ #include <stream.h> typedef void Void; typedef char Char; typedef short Short; typedef int Int; typedef long Long; typedef float Float; typedef double Double; typedef unsigned char UnsignedChar; typedef unsigned short UnsignedShort; typedef unsigned int UnsignedInt; typedef unsigned long UnsignedLong; typedef Int Boolean; typedef ostream Ostream; typedef istream Istream; class Vector3 { Double component[3]; public: Void x(Double x) {component[0]=x;} Void y(Double y) {component[1]=y;} Void z(Double z) {component[2]=z;} Void c(Int c,Double m) {component[c]=m;} Double x() const {return component[0];} Double y() const {return component[1];} Double z() const {return component[2];} Double c(Int n) const {return component[n];} Vector3(Double a=0.0,Double b=0.0,Double c=0.0) {x(a);y(b);z(c);} Vector3(const Vector3 &p) {x(p.x());y(p.y());z(p.z());} Void operator+=(const Vector3 &p) {x(x()+p.x());y(y()+p.y());z(z()+p.z());} Void operator-=(const Vector3 &p) {x(x()-p.x());y(y()-p.y());z(z()-p.z());} Void operator*=(Double a) {x(a*x());y(a*y());z(a*z());} // Problem in here Void operator/=(Double a) {(*this)*=(1.0/a);} Double magnitude2() const {return x()*x()+y()*y()+z()*z();} Double magnitude() const {return sqrt(magnitude2());} Void normalise() {(*this)*=(1.0/magnitude());} Vector3 normalised() const; }; inline Vector3 Vector3::normalised() const return r(*this);{r.normalise();} inline Vector3 operator+(const Vector3 &p,const Vector3 &q) return r(p);{r+=q;} inline Vector3 operator-(const Vector3 &p,const Vector3 &q) return r(p);{r-=q;} inline Vector3 operator-(const Vector3 &p) {return Vector3(-p.x(),-p.y(),-p.z());} inline Vector3 operator*(Double a,const Vector3 &p) return r(p);{r*=a;} inline Vector3 operator*(const Vector3 &p,Double a) return r(p);{r*=a;} inline Vector3 operator/(const Vector3 &p,Double a) return r(p);{r/=a;} inline Boolean operator==(const Vector3 &p,const Vector3 &q) {return (p.x()==q.x() && p.y()==q.y() && p.z()==q.z());} inline Boolean operator!=(const Vector3 &p,const Vector3 &q) {return (p.x()!=q.x() || p.y()!=q.y() || p.z()==q.z());} inline Double operator&(const Vector3 &p,const Vector3 &q) {return p.x()*q.x()+p.y()*q.y()+p.z()*q.z();} /* Dot product */ inline Vector3 operator*(const Vector3 &p,const Vector3 &q) {return Vector3(p.y()*q.z()-p.z()*q.y(), /* Cross product */ p.z()*q.x()-p.x()*q.z(), p.x()*q.y()-p.y()*q.x() ); } Istream& operator>>(Istream &i,Vector3 &v) {Double x,y,z;if (i>>x && i>>y && i>>z) v=Vector3(x,y,z);return i;} Ostream& operator<<(Ostream &o,const Vector3 &v) {o << v.x() << " " << v.y() << " " << v.z();return o;} Void foo(const Vector3 &t) {cout << t << "\n";} main() { Vector3 t(1.0,1.0,1.0); t*=10.0; cout << t << "\n"; // Outputs 10 1 10 on Sun3, (OK on Sun4) foo(t); // But foo output 10 10 10 ! exit(0); } // Looking at the assembler output reveals... // That the first ``cout<<'' is all mixed up with the multiplies, whereas the call to foo // operates on the finished result. I can't follow the inlined cout<< stuff enough to work out what's happening. // The constructors are inline, but don't call inline versions of x(), y() (irrelevant to this problem) // Putting some cerr<<s into operator*= seems to indicate that y() has the right value // after y(a*y()), but then gets clobbered by z()... but something more subtle // must be going on as it contains the right value for the call to foo.