ld "multiple definition of" - One Definition Rule Violations
The linker found the same symbol defined in more than one object file. A function or variable was defined (not just declared) in a header, or a global lives in two translation units - a One Definition Rule violation.
What this error means
Every object compiles, then the link fails with "multiple definition of <symbol>; first defined here". It often appears after a refactor that moved a definition into a header, or under GCC 10+ which defaults to -fno-common.
/usr/bin/ld: b.o:(.bss+0x0): multiple definition of `g_counter'; a.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit statusCommon causes
A definition placed in a header
A non-inline function or a non-inline/non-const global variable defined in a header is compiled into every .cpp that includes it, so the linker sees it defined many times.
GCC 10+ -fno-common tentative definitions
A global declared without extern in a header (a tentative definition) used to be merged under the old common model. GCC 10 defaults to -fno-common, so each unit now defines it and the link clashes.
How to fix it
Declare in the header, define once
Keep only an extern declaration in the header and put the single definition in one .cpp.
// counter.h
extern int g_counter;
// counter.cpp
int g_counter = 0;Mark header definitions inline
- For functions/variables that must live in a header, mark them
inline(C++17inlinevariables) so duplicate definitions are merged. - For globals, use
externin the header and define in exactly one source file. - Do not retry - this is a source/ODR error, not transient.
How to prevent it
- Put declarations in headers and definitions in a single
.cpp. - Use
inlinefor header-only functions and variables. - Build with
-fno-commonlocally so ODR clashes surface before CI.