Global Symbols and Visibility Attributes for Linux* and macOS*

This topic applies to C/C++ applications for Linux* and macOS* only.

A global symbol is one that is visible outside the compilation unit (single source file and its include files) in which it is declared. In C/C++, this means anything declared at file level without the static keyword. For example:

int x = 5;        // global data definition 
extern int y;     // global data reference 
int five()        // global function definition 
  { return 5; } 
extern int four(); // global function reference

A complete program consists of a main program file and possibly one or more shareable object (.so) files that contain the definitions for data or functions referenced by the main program. Similarly, shareable objects might reference data or functions defined in other shareable objects. Shareable objects are so called because if more than one simultaneously executing process has the shareable object mapped into its virtual memory, there is only one copy of the read-only portion of the object resident in physical memory. The main program file and any shareable objects that it references are collectively called the components of the program.

Each global symbol definition or reference in a compilation unit has a visibility attribute that controls how (or if) it may be referenced from outside the component in which it is defined. There are five possible values for visibility:

Static local symbols (in C/C++, declared at file scope or elsewhere with the keyword static) usually have HIDDEN visibility— they cannot be referenced directly by other components (or, for that matter, other compilation units within the same component), but they might be referenced indirectly.

Note

Visibility applies to references as well as definitions. A symbol reference's visibility attribute is an assertion that the corresponding definition will have that visibility.

Specify Symbol Visibility Explicitly

You can explicitly set the visibility of an individual symbol using the visibility attribute on a data or function declaration. For example:

int i __attribute__ ((visibility("default"))); 
void __attribute__ ((visibility("hidden"))) x () {...} 
extern void y() __attribute__ ((visibility("protected")));

The visibility declaration attribute accepts one of the five keywords:

The value of the visibility declaration attribute overrides the default set by the options -fpic, -fvisibility, or -fno-common .

If you have a number of symbols for which you wish to specify the same visibility attribute, you can set the visibility using one of the five command line options:

where file is the pathname of a file containing a list of the symbol names whose visibility you wish to set.

The symbol names in the file are separated by white space (blanks, TAB characters, or newlines). For example, the command line option: -fvisibility-protected=prot.txt, where file prot.txt contains:

a
    b c d
  e

This sets protected visibility for symbols a, b, c, d, and e.

This has the same effect as __attribute__ ((visibility=("protected"))) on the declaration for each of the symbols.

Note

These two ways to explicitly set visibility are mutually exclusive– you may use __attribute((visibility())) on the declaration or specify the symbol name in a file, but not both.

You can set the default visibility for symbols using one of the command line options:

This option sets the visibility for symbols not specified in a visibility list file and that do not have __attribute__ ((visibility=())) in their declaration. For example, the command line options: -fvisibility=protected -fvisibility-default=prot.txt, where file prot.txt is as previously described, will cause all global symbols except a, b, c, d, and e to have protected visibility. Those five symbols, however, will have default visibility, and thus will be preemptable.