7

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:

wayland-client.h:

void wl_event_queue_destroy(struct wl_event_queue *);

wayland-client.c:

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.

djsp
  • 2,174
  • 2
  • 19
  • 40
  • public headers can absolutely have code that isn't visibly exported, such as struct definitions, constants, inline functions, ect. While it is probably bad practice, it can also declare functions that should only be used internal to the dll. Having the symbols in the headers can allow fancy tricks in importing the files (such as implicit linking in MSVC). Of course this is all platform dependent, as exposing public symbols is done differently in ELF and DLLs. So uh...whats your question? – IdeaHat Oct 10 '14 at 14:05
  • 1
    @MadScienceDreams My question is: Where should the _visibility_ (GCC) attribute be specified: in declarations (headers) or in definitions (source files)? I am also concerned as to whether this is the same across all implementations of the "symbol visibility" concept, i.e., whether the answer applies to Microsoft's _dllexport_. – djsp Oct 10 '14 at 15:10
  • quick answer is it does not apply for microsofts `dllexport`/`dllimport`. All declaration must have one of them, and all definitions must have `dllexport`. see http://msdn.microsoft.com/en-us/library/y4h7bcy6.aspx. For cross compilable code, I'd put `ifdef` macros in the header to specify compiler, define the macro to the correct value, and then *put it in both*. – IdeaHat Oct 10 '14 at 16:37

1 Answers1

1

It does not really matter for GNU but on Windows header declarations need to be annotated with dllimports anyway so it's customary to put visibility annotations there as well.

Note that visiblity annotations only need to be enabled when compiling the library itself, not when compiling code which merely calls library functions so most projects do something like

#ifndef WL_EXPORT
# define WL_EXPORT
#endif

in headers.

yugr
  • 19,769
  • 3
  • 51
  • 96