I'm experimenting with C++ symbol visibility on Linux and gcc. It seems that the preferred way is to use -fvisibility=hidden, and export used symbols one-by-one according to Visibility gcc wiki page (http://gcc.gnu.org/wiki/Visibility). My problem is that many libraries does not handle this well, they forget to explicitly export symbols, which is a serious problem. After several fixed bugs even some parts of boost may still be affected. Of course those bugs should be fixed, but till that I would like to use a "safe" way to hide as much as symbols as possible.
I came up with a solution: I place all the symbols in a namespace and I use symbol hide attribute on that and export the public interface, this way only my symbols can be affected.
The problem is that I got a warning message when I compile something against that library for every class that I haven't exported and I use in the application as class field.
namespace MyDSO __attribute__ ((visibility ("hidden"))) {
struct Foo {
void bar() __attribute__ ((visibility ("default"))) {}
};
}
struct Bar {
MyDSO::Foo foo;
};
int main() {}
The warning message can be reproduced in this small example, but of course the namespace should be in a library the other class in the application.
$ gcc-4.7.1 namespace.cpp -o namespace
namespace.cpp:7:8: warning: ‘Bar’ declared with greater visibility than the type of its field ‘Bar::foo’ [-Wattributes]
As I understand symbol visibility, hiding namespace should have quite similar effect to using -fvisibility=hidden, but I never got similar warnings using the latter. I see that when I pass -fvisibility=hidden to the application the class in the application will also be hidden, so I won't get a warning. But when I don't pass the option none of the symbols in the headers will seem hidden to the compiler, so I won't get a warning again.
What is the propose of this warning message? Is it a serious problem? In which situations can this cause any problem? How hiding namespace is different to fvisibility=hidden?