This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Possible bug with friend operator to template class
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Possible bug with friend operator to template class
- From: "Skvarenina Peter - 5ZA51/9" <skvaren at fred dot fri dot utc dot sk>
- Date: Tue, 18 Jan 100 11:53:29 +0100 (MET)
It looked to me that I've found a bug in GCC 2.95.2 (it appears to me as bug,
because this will compile and run without any problems under EGCS 1.1.2).
Here are two files: Vector.h and VecTest.cpp. I've tried to declare template
struct sVector<Number> with some operators (+,-,*,^). When I added friend
declaration: friend sVector<Number> operator * <> (Number, sVector<Number>),
that I could do multiplication with Number from the left, compiler produced
this output:
Vector.h: In instantiation of `sVector<int>':
vectest.cpp:6: instantiated from here
Vector.h:72: invalid use of undefined type `struct sVector<int>'
Vector.h:73: forward declaration of `struct sVector<int>'
Vector.h:72: confused by earlier errors, bailing out
When I commented out operator * (Number) and operator * (sVector<Number>) and
slightly modified VecTest.cpp (to remove affected lines and added C = 5 * A to
invoke operator * (Number, sVector<Number>)), everything was fine.
Then I tried to remove template declarations and replace Number with int
in original files, and everything worked fine too. So I switched back into
originals and changed struct to class with public: before constructor.
That wasn't fine :( The same error as above. Maybe it is not a bug, but my
misunderstanding of GCC, or new ISO feature :). It'll be very nice from you,
if you find the bug and notice me (as I noticed you :).
This is Vector.h:
-----------------
#ifndef _Vector_
#define _Vector_
#include <math.h>
template <class Number>
struct sVector;
template <class Number>
sVector<Number> operator * (Number, sVector<Number>);
template <class Number>
struct sVector
{
Number X, Y, Z;
sVector ()
{
X = Y = Z = 0;
}
sVector (Number x, Number y, Number z)
{
X = x;
Y = y;
Z = z;
}
void Unit ()
{
Number D = Length ();
X = X / D;
Y = Y / D;
Z = Z / D;
}
Number Length ()
{
return sqrt (X * X + Y * Y + Z * Z);
}
sVector<Number> operator + (sVector<Number> B)
{
return sVector<Number> (X + B.X, Y + B.Y, Z + B.Z);
}
sVector<Number> operator - (sVector<Number> B)
{
return sVector<Number> (X + B.X, Y + B.Y, Z + B.Z);
}
// Vector product
sVector<Number> operator * (sVector<Number> B)
{
return sVector<Number> (Y * B.Z - Z * B.Y, Z * B.X - X * B.Z, X * B.Y - Y * B.X);
}
// Vector * number
sVector<Number> operator * (Number B)
{
return sVector<Number> (X * B, Y * B, Z * B);
}
// scalar product
Number operator ^ (sVector<Number> B)
{
return X * B.X + Y * B.Y + Z * B.Z;
}
// Number * vector
friend sVector<Number> operator * <> (Number, sVector<Number>);
};
// Number * vector
template <class Number>
sVector<Number> operator * (Number A, sVector<Number> B)
{
return sVector<Number> (A * B.X, A * B.Y, A * B.Z);
}
#endif
And this is VecTest.cpp:
------------------------
#include "Vector.h"
#include <stdio.h>
int main ()
{
sVector<int> A(2,2,1);
sVector<int> B(-1,3,2);
sVector<int> C;
C = A * B + B * 3;
//A = 3 * B; // Could be uncommented for EGCS 1.1.2
printf ("%d %d %d\n",C.X, C.Y, C.Z);
return 0;
}
I've tried to compile this with these compilers:
------------------------------------------------
Reading specs from C:\Program\MinGW32\Bin\..\lib\gcc-lib\i386-mingw32\2.95.2\specs
gcc version 2.95.2 19991024 (release)
--> FAILED
Reading specs from c:/program/djgpp/lib/gcc-lib/djgpp/2.952/specs
gcc version 2.95.2 19991024 (release)
--> FAILED
also gcc 2.95.2 on glibc 2.1/Linux FAILED
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
--> COMPILED
Peter