Go to main content
Oracle® Developer Studio 12.5: C++ User's Guide

Exit Print View

Updated: July 2016
 
 

4.1 Linker Scoping

Use the following declaration specifiers to help constrain declarations and definitions of extern symbols. The scoping restraints you specify for a static archive or an object file will not take effect until the file is linked into a shared library or an executable. Despite this, the compiler can still perform some optimization given the presence of the linker scoping specifiers.

By using these specifiers, you no longer need to use mapfiles for linker scoping. You can also control the default setting for variable scoping by specifying -xldscope on the command line.

For more information, see -xldscope={v}.

Table 20  Linker Scoping Declaration Specifiers
Value
Meaning
__global
Symbol definitions have global linker scoping and is the least restrictive linker scoping. All references to the symbol bind to the definition in the first dynamic load module that defines the symbol. This linker scoping is the current linker scoping for extern symbols.
__symbolic
Symbol definitions have symbolic linker scoping, which is more restrictive than global linker scoping. All references to the symbol from within the dynamic load module being linked bind to the symbol defined within the module. Outside of the module, the symbol appears as though it were global. This linker scoping corresponds to the linker option -Bsymbolic. Although you cannot use -Bsymbolic with C++ libraries, you can use the __symbolic specifier without causing problems. See the ld(1) man page for more information on the linker.
__hidden
Symbol definitions have hidden linker scoping. Hidden linker scoping is more restrictive than symbolic and global linker scoping. All references within a dynamic load module bind to a definition within that module. The symbol will not be visible outside of the module.

A symbol definition may be redeclared with a more restrictive specifier, but may not be redeclared with a less restrictive specifier. A symbol may not be declared with a different specifier once the symbol has been defined.

__global is the least restrictive scoping, __symbolic is more restrictive, and __hidden is the most restrictive scoping.

All virtual functions must be visible to all compilation units that include the class definition because the declaration of virtual functions affects the construction and interpretation of virtual tables.

You can apply the linker scoping specifiers to struct, class, and union declarations and definitions because C++ classes may require generation of implicit information, such as virtual tables and runtime type information. The specifier, in this case, follows the struct, class, or union keyword. Such an application implies the same linker scoping for all its implicit members.

4.1.1 Compatibility with Microsoft Windows

For compatibility with similar scoping features in Microsoft Visual C++ (MSVC++) for dynamic libraries, the following syntax is also supported:

__declspec(dllexport) is equivalent to __symbolic
__declspec(dllimport) is equivalent to __global

When taking advantage of this syntax with Oracle Developer Studio C++, you should add the option -xldscope=hidden to CC command lines. The result will be comparable to the results using MSVC++. With MSVC++, __declspec(dllimport) is supposed to be used only on declarations of external symbols, not on definitions. Example:

__declspec(dllimport) int foo(); // OK 
__declspec(dllimport) int bar() { ... } // not OK  

MSVC++ is lax about allowing dllimport on definitions, and the results using Oracle Developer Studio C++ will be different. In particular, using dllimport on a definition using Oracle Developer Studio C++ results in the symbol having global linkage instead of symbolic linkage. Dynamic libraries on Microsoft Windows do not support global linkage of symbols. If you run into this problem, you can change the source code to use dllexport instead of dllimport on definitions. You will then get the same results with MSVC++ and Oracle Developer Studio C++.