This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Code compiled fine under 2.8.1 but fails to compile under 2.95.1
- To: chas at secant dot com
- Subject: Re: Code compiled fine under 2.8.1 but fails to compile under 2.95.1
- From: "Martin v. Loewis" <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Date: Wed, 13 Oct 1999 11:17:23 +0200
- CC: gcc-bugs at gcc dot gnu dot org, oliva at lsd dot ic dot unicamp dot br
- References: <37FB71CA.34822E10@secant.com>
> template <class T>
> class Node
> {
> T key;
> public:
> Node(T _key ) : key(_key) { }
> ~Node();
> };
>
> void fnc()
> {
> int x= 1;
> Node<int>(1);
> }
>
> template <>
> Node<int> :: ~Node() {}
>
> I have several questions about why this will not compile under the
> latest gcc, but will under most other compilers (4/6 offer no
> complaints, 1 warns about future error, gcc errors). As I
> understand, the basic rule for templates is specialization before
> instantiation (expansion) of the general case. The key question is,
> when does this instantiation occur?
The rule is that a template is instantiated when it is "used"; see the
C++ standard for a definition of "used". Instantiation of a class
template does not, automaticalls, mean that the member templates are
instantiated.
Your code is clearly incorrect: Inside fnc, you instantiate the class
template Node<1>, and then create a temporary object. This temporary
object is automatically deleted, which requires instantiation of the
destructor. However, the destructor has not been defined, and is not
declared external, so your program is in error.
Other compilers can legitimately accept this code, for two reasons:
a) they could offer extensions over standard C++. In a conforming
mode, they would need to diagnose usage of such extensions. Most
compilers provide extensions in the way templates are processed.
b) I believe this error (template not defined at point of
instantiation) does not require a diagnosis. So compilers not
diagnosing the error (or perhaps only at link time) would be still
conforming. That does not make the code well-formed.
> Does instantiation of all members of a template class occur at the
> same time?
No, see above.
> How can the compiler instantiate the destructor for Node<int> when
> no definition has been provided?
It cannot. If you attempted to link the program, you'd get an error
undefined reference to `Node<int>::~Node(void)'
> My recommendation is that template class methods which are not
> defined at the time of the class instantiation are not considered
> instantiated for the purpose of "specialization after instantiation"
> error checking. A lack of these methods in the program will be
> detected at link time.
You would need to make this recommendation to the C++
committee. Please discuss C++ language definition issues in
comp.lang.c++.moderated.
Thanks,
Martin