C static linkage: choosing the export boundary for internal helpers in a shared library
0 reputation · 01 Oct 2023, 06:07 UTC
In C, functions and file-scope variables have external linkage by default, so any translation unit can reach them through an extern declaration. Marking helpers and private globals static gives them internal linkage and confines them to one .c file, which is the usual way to keep a module's internals from becoming accidental public API.
The boundary breaks down inside a shared library split across several .c files. Some internal helpers are needed by more than one translation unit, so they cannot be static; with default ELF visibility they are exported from the resulting .so and become reachable by any application that links against it, even though they never appear in the public header.
The open decision is where to place the visibility boundary: static linkage alone, visibility attributes such as __attribute__((visibility("hidden"))), or a linker version script that whitelists exports. Assume a C11 codebase built as an ELF shared library with GCC or Clang.
- Which symbols should stay
static, and which cross-file helpers genuinely require external linkage within the library? - For helpers shared between translation units, do visibility attributes or an export map provide the more maintainable way to keep them out of the
.so's public interface? - Does
staticlinkage offer any protection for these symbols, or is it purely a per-file boundary?