🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by T.Day Mon, 18 Dec 1989 16:10
Optimisation problems when using const
#2105
Author: T.Day
Date: Mon, 18 Dec 1989 16:10
109 lines
5087 bytes
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.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads