In his paper about shared libraries, Ulrich Drepper recommends that symbol visibility is globally set to hidden when building the library, and then, in the source code, set to default for each symbol that is meant to be public to export it. However, and after searching it, I still don't understand where should the visibility attribute be specified: in declarations, or in definitions? Since any symbol that is not meant to be part of the interface won't be declared in the public headers, I think the later option is better, but this page from Microsoft makes me doubt: there, the corresponding attribute seems to be set in headers.
For instance, in libwayland, an open-source implementation of the Wayland protocol, it is done as follows:
void wl_event_queue_destroy(struct wl_event_queue *);
WL_EXPORT void
wl_event_queue_destroy(struct wl_event_queue *)
{
/* ... */
}
I am concerned about compatibility with other compilers and platforms: GCC, Clang, MSVC,... Also note that this question applies to C++ as well.