Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with C++ template arguments with hidden visibility

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 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?

like image 211
Geoffrey Irving Avatar asked Mar 21 '11 16:03

Geoffrey Irving


1 Answers

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?

like image 186
Void Avatar answered Jan 05 '23 17:01

Void