This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Code compiled fine under 2.8.1 but fails to compile under 2.95.1


> 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]