Intel® oneAPI DPC++/C++ Compiler Developer Guide and Reference

ID 767253
Date 3/22/2024
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Global Symbols and Visibility Attributes for Linux*

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. The visibility attribute accepts one of five keywords values:

  • external: The compiler must treat the symbol as though it is defined in another component. For a definition, this means that the compiler must assume that the symbol will be overridden (preempted) by a definition of the same name in another component. See Symbol Preemption. If a function symbol has external visibility, the compiler knows that it must be called indirectly and can inline the indirect call stub.

  • default: Other components can reference the symbol. Furthermore, the symbol definition may be overridden (preempted) by a definition of the same name in another component.

  • protected: Other components can reference the symbol, but it cannot be preempted by a definition of the same name in another component.

  • hidden: Other components cannot directly reference the symbol. However, its address might be passed to other components indirectly (for example, as an argument to a call to a function in another component, or by having its address stored in a data item reference by a function in another component).

  • internal: The symbol cannot be referenced outside its defining component, either directly or indirectly.

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 value of the visibility declaration attribute overrides the default set by the options -fpic or -fno-common .