I'm compiling the following code under gcc with -fvisibility=hidden:
template<class T> struct /*__attribute__ ((visibility("default")))*/ A {};
template<class T> struct B
{
B() __attribute__ ((visibility("default")));
};
template<class T> B<T>::B() {}
template class B<int>;
template class B<A<int> >;
If I run the resulting object file through nm | grep B, I get
000000000002b97c t B<A<int> >::B()
000000000002b972 t B<A<int> >::B()
000000000002b968 T B<int>::B()
000000000002b95e T B<int>::B()
I.e., B<int>
is visible 开发者_Python百科but B<A<int> >
is invisible. B<A<int> >
becomes visible if I uncomment the snippet marking A<T>
as visible. However, I do not want to mark all of A visible, since in the real code A<T>
contains a vast number of methods which should remain private.
Why does the visibility of A<T>
affect the visibility of B<A<T> >
? Can I make B<A<T> >
visible without making all of A<T>
visible?
Assuming I understand the ODR correctly (I likely do not :)), hiding your B<A<int> >
instantatiation looks like an ODR related requirement. If B<A<int> >
was not hidden it would be possible for multiple instantations of A<>
's members to exist and be referenced, resulting in an ODR violation. GCC's symbol visibility Wiki briefly describes such violations when using hidden symbol visibility on "entities" with vague linkage, including templates (see the section on exceptions).
What are you trying to achieve by hiding the symbols in your A<>
template?
If you specifically wish to hide the inline methods of A<> try using -fvisibility-inlines-hidden
精彩评论