J
JurgenvonOerthel
Consider the following code (in three files: base.h, base.cc &
main.cc):
base.h:
---------
template <typename T> class Base {
public :
virtual ~Base();
};
base.cc:
----------
#include "base.h"
template class Base<int>; // NOTE: Definition of type Base is
incomplete!
template <class T>
Base<T>::~Base() {
}
main.cc:
-----------
#include "base.h"
template <typename T> class Derived : public Base<T> {
public:
virtual ~Derived() {}
};
template class Derived<int>;
int main () {
Derived<int> p;
return 0;
}
Compile:
-----------
g++ -c base.cc -g -W -Wall -m32 -fno-implicit-templates -std=c++98 -o
base.o
g++ -c main.cc -g -W -Wall -m32 -fno-implicit-templates -std=c++98 -o
main.o
g++ -m32 base.o main.o
===================
With g++ 3.4.4 this compiles and links without problems.
With g++ 4.2.2 this causes link errors because the destructors of
Base<int> are not generated in Base.o. No diagnostics are produced by g
++ however.
When I move the instantiation of Base<int> after the definition of the
destructor it compiles and links fine.
My question is:
Is explicitly instantiating an incomplete template class allowed,
undefined behaviour or is the program ill-formed?
main.cc):
base.h:
---------
template <typename T> class Base {
public :
virtual ~Base();
};
base.cc:
----------
#include "base.h"
template class Base<int>; // NOTE: Definition of type Base is
incomplete!
template <class T>
Base<T>::~Base() {
}
main.cc:
-----------
#include "base.h"
template <typename T> class Derived : public Base<T> {
public:
virtual ~Derived() {}
};
template class Derived<int>;
int main () {
Derived<int> p;
return 0;
}
Compile:
-----------
g++ -c base.cc -g -W -Wall -m32 -fno-implicit-templates -std=c++98 -o
base.o
g++ -c main.cc -g -W -Wall -m32 -fno-implicit-templates -std=c++98 -o
main.o
g++ -m32 base.o main.o
===================
With g++ 3.4.4 this compiles and links without problems.
With g++ 4.2.2 this causes link errors because the destructors of
Base<int> are not generated in Base.o. No diagnostics are produced by g
++ however.
When I move the instantiation of Base<int> after the definition of the
destructor it compiles and links fine.
My question is:
Is explicitly instantiating an incomplete template class allowed,
undefined behaviour or is the program ill-formed?