问题
Is there an easy way to see whether a class has been instantiated in a translation unit? An exercise from C++ Primer asks for each labelled statement, whether an instantiation happens:
template <typename T> class Stack { };
void f1(Stack<char>); // (a)
class Exercise {
Stack<double> &rsd; // (b)
Stack<int> si; // (c)
};
int main() {
Stack<char> *sc; // (d)
f1(*sc); // (e)
int iObj = sizeof(Stack< string >); // (f)
}
I'm not sure how I could actually check my answers for these. I thought maybe I could use explicit instantiations for each class type (e.g. extern template class Stack<char>
) and then never have a corresponding explicit instantiation definition in the program. That way if something was instantiated, if the definition didn't later appear then the linker would kick up an error.
However the compiler/linker doesn't always recognise such an error:
template <typename T> class A{ };
extern template class A<int>;
int main(){
A<int> a;
}
This compiles fine on gcc 4.9.2. However if this was the only object file in my program is should be an error as far as I can tell from [14.7.2][11] of N3337:
If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration. An entity that is the subject of an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit instantiation (14.7.1) in the translation unit shall be the subject of an explicit instantiation definition somewhere in the program; otherwise the program is ill-formed, no diagnostic required.
(I'm guessing the "no diagnostic required" is why this doesn't kick up an error?). Alternatively is it the case that instantiations happen whenever an incomplete class type isn't viable for an expression - so that I could check by removing the definition of Stack
?
template <typename T> class Stack;
So that each incomplete type error corresponds to a place where an instantiation would have occured?
回答1:
You can use the nm tool on the executable. This will show what file contains function definitions. Also gcc provides a flag to strip out unused functions when doing the link.
Compile with “-fdata-sections” to keep the data in separate data sections and “-ffunction-sections” to keep functions in separate sections, so they (data and functions) can be discarded if unused. Link with “–gc-sections” to remove unused sections.
来源:https://stackoverflow.com/questions/33453352/checking-whether-a-class-template-has-been-instantiated