If your shared library uses C++ inside, then all the std::
templates and types referenced by it will be exported as weak symbols. Even if you use -fvisiblity=hidden
and -Wl,--exclude-libs,ALL
. The only way to hide those symbols is using a version script.
What's the purpose of these forced exports?
Is there any harm in hiding them with version scripts?
So I found two (rejected) GCC-bugreports discussing this issue:
The reasoning seems to be:
Check out this comment by Benjamin Kosnik especially. Cited for preservation purposes:
This isn't a bug, but rather part of a deliberate linkage strategy.
For C++, types that are to be used across shared libraries have to be visible. See:
http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options
And in particular:
Note that '-fvisibility' does affect C++ vague linkage entities. This means that, for instance, an exception class that will be thrown between DSOs must be explicitly marked with default visibility so that the 'type_info' nodes will be unified between the DSOs.
Thus, the rationale for libstdc++ having namespace std have visibility "default." If you were to hack in support for allowing namespace std to have hidden visibility, and run the testsuite with -fvisibility=hidden (see attached patch) you would notice the breakdown in testresults, with mass failures. Thus, it is provided for information purposes only.
In the libstdc++ source files, anonymous namespaces are used for specific entities that have both local/hidden linkage. This use of anonymous namespaces is considered superior to attribute hidden as it uses ISO C++ and is thus more portable than vendor extensions (pragmas or attributes).
However, in libstdc++ header files, attribute hidden has been difficult to use. One might think that perhaps all the implementation details could be moved to say std::__detail, and then marked with attribute hidden. Then, many of these helper functions would be marked as hidden in your example below.
There are some pitfalls with this approach:
- all these implementation base types that are used by default derived classes would have to be default
- same with implementation details that use static locals
- same with virtual functions, etc etc.
- thus you end up with a pretty limited set of hidden things
In addition, this may exacerbate the dlopen + RTLD_LOCAL + weak symbol issue for C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With