Function Visibility in C++
- Function visibility across translation units.
- Symbol visibility in shared libraries.
1. Introduction
In C++, function visibility generally pertains to whether a function can be accessed from outside the translation unit in which it’s defined. Control over function visibility is essential for modular code, particularly in libraries.
2. Internal vs. External Linkage
Functions with internal linkage are visible only within the translate unit. Marking a function as static
limits its visibility, meaning it can’t be used or “seen” outside that file. This helps avoid name conflicts across multiple files.
1 | static void internalFunction() { |
A useful remind for using static
in a header file:
When you put a static
variable definition in a header file, every .cpp file that includes that header will get its own separate instance of the static variable. This means:
- Each translation unit (each .cpp file) that includes the .h file will have its own unique copy of the static variable, rather than sharing one.
- The static variable is not shared across translation units because static gives the variable internal linkage.
By default, functions without the static
keyword have external linkage. This means they are visible to other translation units and can be used from other files, assuming they are declared in a shared header file.
1 | void externalFunction() { |
3. extern Linkage
The extern
keyword in C++ is used for various purposes related to linkage and visibility of variables and functions. A function decorated with extern
should only be defined once in its own translate unit. When shared across other translate units, it needs to be declared before using it. However, since functions without static
have external linkage by default, simple forward declaration also works.
1 | // a.cpp |
4. extern “C” for C Linkage
Purpose of extern “C”: When compiling in C++, function names are mangled to include extra information like return type and parameter types, enabling C++ to support function overloading. However, this name mangling means C++ functions have different names than C functions, making it difficult to link C++ code with C libraries.
To solve this, extern “C” is used to instruct the compiler not to mangle the names of the functions declared within it, making them compatible with C linkage. This is often used in headers for C libraries to allow the functions to be linked and used in C++ code.
1 |
|
5. extern with const Variables
In C++, const
global variables have internal linkage by default (they are restricted to the file in which they’re defined). This prevents unintended access or modification, but if you need to access a const variable from other files, you can declare it with extern to give it external linkage.
1 | // a.cpp |
6. Controlling Visibility in Shared Libraries
__attribute__((visibility("default")))
: When creating shared libraries, function visibility can be controlled using this attribute on compilers like GCC and Clang. Functions marked with “default” visibility are exported and accessible outside the shared library.
1 | __attribute__((visibility("default"))) void exportedFunction() { |
It is common to define a macro that controls function or variable visibility.
1 |
|
Function Visibility in C++
http://chuzcjoe.github.io/2024/11/07/cpp-function-visibility/