Possible g++ bug in template parsing

R

Rennie deGraaf

The attached code compiles and works properly when I comment out the
declaration, definition, and invocations of the method 'eck'. With
"eck" in there, g++ fails with

ttest.cpp:23: template-id `eck<>' for `void blah<int>::eck(int)'
does not match any template declaration
ttest.cpp:23: syntax error before `{' token
ttest.cpp:25: syntax error before `<<' token

Note that 'gak' (a template function in a template class) works, as
does
'ugh" (a normal function in a specialized template class); it's only
'eck', a template function in a specialized template class, that
fails.

The compiler was g++ 3.2.2 20030222 on Red Hat 9 i386.

g++ 2.95.3 on Solaris SPARC 8 failed, with a different error.

It did compile and run on Solaris 8 using Sun's C++ compiler. This
doesn't help me much, since the code must run on Linux i386, but
suggests that the code is probably valid.

Unfortunately, I don't have access to a system with a latest-release
gcc to test.

Do I have a gcc bug, or is this code actually invalid?

If it is a bug, does anyone know of a workaround I could use for the
time being? If it's bad code, then what am I doing wrong? Is Sun's
CC in error compiling this?

Thanks for the help.


Rennie deGraaf

-------------------------------------

#include <iostream>
#include <typeinfo>
using namespace std;

template <class TYPE>
class blah
{
TYPE feh;
public:
void blech(int x);
template <class T> void gak(int x);endl; }
template <class T> void eck(int x);
void ugh(int x);
};

template <class TYPE> template <class T> void blah<TYPE>::gak(int x)
{
T a;
cout << typeid(a).name() << endl;
}

template <> template <class T> void blah<int>::eck(int x)
{
T a;
cout << typeid(a).name() << typeid(feh).name() << endl;
}

template <class TYPE> void blah<TYPE>::blech(int x)
{
cout << typeid(feh).name() << endl;
}

template <> void blah<int>::ugh(int x)
{
cout << typeid(feh).name() << endl;
}


/*template <> template <class T> void blah<char>::eck(int x)
{
T a;
cout << "calling blah<char>::eck(int) " << typeid(feh).name() <<
"\n";
}*/



template <class T>
void foobar(int x)
{
T a;
cout << typeid(a).name() << endl;
}

int main()
{
cout << "call foobar with int: ";
foobar<int>(1);
cout << "call foobar with char: ";
foobar<char>(1);
cout << "call foobar with short: ";
foobar<float>(1);
cout << "call foobar with int*: ";
foobar<int*>(1);

blah<int> a;
blah<char> b;
blah<float> c;
blah<int*> d;

cout << "call blah<int>.blech(): ";
a.blech(1);
cout << "call blah<char>.blech(): ";
b.blech(1);
cout << "call blah<float>.blech(): ";
c.blech(1);
cout << "call blah<int*>.blech(): ";
d.blech(1);

cout << "call blah<int>.gak<float>(): ";
a.gak<float>(1);

cout << "call blah<int>.ugh(): ";
a.ugh(1);
// cout << "call blah<char>.ugh(): ";
// b.ugh(1); // this isn't defined, and
shouldn't work

cout << "call blah<int>.eck<float>(): ";
a.eck<float>(1);
// cout << "call blah<char>.eck<float>(): ";
// b.eck<float>(1); // this isn't defined, and
shouldn't work


return 0;
}
 
D

David B. Held

Rennie deGraaf said:
The attached code compiles and works properly when I comment
out the declaration, definition, and invocations of the method 'eck'.
With "eck" in there, g++ fails with

ttest.cpp:23: template-id `eck<>' for `void blah<int>::eck(int)'
does not match any template declaration
ttest.cpp:23: syntax error before `{' token
ttest.cpp:25: syntax error before `<<' token

I think this is correct.
Note that 'gak' (a template function in a template class) works,
as does 'ugh" (a normal function in a specialized template class);
it's only 'eck', a template function in a specialized template class,
that fails.
[...]
Do I have a gcc bug, or is this code actually invalid?

Bad code.
If it is a bug, does anyone know of a workaround I could use for
the time being? If it's bad code, then what am I doing wrong?
Is Sun's CC in error compiling this?

Looks like it to me.
[...]
template <class TYPE>
class blah
{
TYPE feh;
public:
void blech(int x);
template <class T> void gak(int x);endl; }

This obviously isn't a cut-n-paste, or this line shouldn't compile.
template <class T> void eck(int x);
void ugh(int x);
};

template <> template <class T> void blah<int>::eck(int x)
{
T a;
cout << typeid(a).name() << typeid(feh).name() << endl;
}
[...]
template <> void blah<int>::ugh(int x)
{
cout << typeid(feh).name() << endl;
}
[...]

At no point do you define the specialization:

template <>
class blah<int>
{
...
};

Therefore, defining member functions of this specialization
is illegal. The solution is to define the class specialization.

Dave
 
R

Rennie deGraaf

David B. Held said:
Rennie deGraaf said:
The attached code compiles and works properly when I comment
out the declaration, definition, and invocations of the method 'eck'.
With "eck" in there, g++ fails with

ttest.cpp:23: template-id `eck<>' for `void blah<int>::eck(int)'
does not match any template declaration
ttest.cpp:23: syntax error before `{' token
ttest.cpp:25: syntax error before `<<' token

I think this is correct.
Note that 'gak' (a template function in a template class) works,
as does 'ugh" (a normal function in a specialized template class);
it's only 'eck', a template function in a specialized template class,
that fails.
[...]
Do I have a gcc bug, or is this code actually invalid?

Bad code.
If it is a bug, does anyone know of a workaround I could use for
the time being? If it's bad code, then what am I doing wrong?
Is Sun's CC in error compiling this?

Looks like it to me.
[...]
template <class TYPE>
class blah
{
TYPE feh;
public:
void blech(int x);
template <class T> void gak(int x);endl; }

This obviously isn't a cut-n-paste, or this line shouldn't compile.

Sorry about that; I deleted a multi-line comment when I posted it, and
evidently missed part. The rest IS a cut-and-paste.
template <class T> void eck(int x);
void ugh(int x);
};

template <> template <class T> void blah<int>::eck(int x)
{
T a;
cout << typeid(a).name() << typeid(feh).name() << endl;
}
[...]
template <> void blah<int>::ugh(int x)
{
cout << typeid(feh).name() << endl;
}
[...]

At no point do you define the specialization:

template <>
class blah<int>
{
...
};

Therefore, defining member functions of this specialization
is illegal. The solution is to define the class specialization.

Then how come this is accepted, and works properly?

template <> void blah<int>::ugh(int x)
{
cout << typeid(feh).name() << endl;
}
 
D

David B. Held

Rennie deGraaf said:
[...]
Then how come this is accepted, and works properly?

template <> void blah<int>::ugh(int x)
{
cout << typeid(feh).name() << endl;
}

Because the compiler is broken? Usually, when something
unexpectedly works, something else (that should) doesn't.
Try this, for instance, define the specialization *after* this
definition, and see what the compiler says.

Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top