C++ multiple definition Error | 'Duplicate Definition' Linker Error Complete Solution

C++ multiple definition Error | 'Duplicate Definition' Linker Error Complete Solution

이 글의 핵심

C++ multiple definition error C++, multiple, definition, Introduction: "Compiles but multiple definition at link..." explained in detail with practical examples.

"Defined function in header file and got error”

When splitting C++ project into multiple files, you encounter multiple definition of error. Compilation succeeds but fails at link stage.

Here is detailed implementation code using C++. Import the necessary modules. Understand the role of each part while examining the code.

// utils.h
void foo() {  // ❌ Definition in header
    std::cout << "foo\n";
}

// main.cpp
#include "utils.h"

// other.cpp
#include "utils.h"

// Link error:
// multiple definition of 'foo()'
// first defined here: main.o
// also defined here: other.o

What This Guide Covers:

  • Why multiple definition error occurs
  • Understanding ODR (One Definition Rule)
  • 5 major causes and solutions
  • Header file writing rules
  • Difference between inline, static, extern

1. What is multiple definition Error?

Error Message

Here is a simple text code example. Ensure stability through error handling. Try running the code directly to check its operation.

/usr/bin/ld: other.o: in function `foo()':
other.cpp:(.text+0x0): multiple definition of `foo()'; 
main.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Meaning: foo() function is defined in both main.o and other.o, linker does not know which to use.


2. ODR (One Definition Rule)

Rule

C++ standard’s ODR (One Definition Rule):

  1. Variable/function must be defined at most once in entire program
  2. Class/template/inline function can be defined multiple times (but all must be identical)

ODR Violation Example

Below is an implementation example using C++. Try running the code directly to check its operation.

// ❌ ODR violation
// file1.cpp
int globalVar = 42;

// file2.cpp
int globalVar = 99;  // ❌ Duplicate definition

// Link error: multiple definition of 'globalVar'

ODR Compliant Example

Below is an implementation example using C++. Import the necessary modules. Understand the role of each part while examining the code.

// ✅ ODR compliant
// header.h
extern int globalVar;  // Declaration only

// file1.cpp
int globalVar = 42;  // Definition (in one place only)

// file2.cpp
#include "header.h"
// Can use globalVar (no definition)

3. Five Major Causes and Solutions

Cause 1: Function Definition in Header

Most common cause: Defining regular function in header file.

Below is an implementation example using C++. Import the necessary modules. Understand the role of each part while examining the code.

// ❌ utils.h
void foo() {  // Definition in header
    std::cout << "foo\n";
}

// main.cpp
#include "utils.h"

// other.cpp
#include "utils.h"

// Link error: multiple definition of 'foo()'

Solution 1: Separate Declaration and Definition (Recommended)

Below is an implementation example using C++. Try running the code directly to check its operation.

// ✅ utils.h
void foo();  // Declaration only

// utils.cpp
void foo() {  // Definition
    std::cout << "foo\n";
}

Solution 2: inline Keyword

Here is a simple C++ code example. Try running the code directly to check its operation.

// ✅ utils.h
inline void foo() {  // inline: allows multiple definitions
    std::cout << "foo\n";
}

Solution 3: static Keyword (Not Recommended)

Here is a simple C++ code example. Try running the code directly to check its operation.

// ✅ utils.h
static void foo() {  // Separate copy for each .cpp
    std::cout << "foo\n";
}

Caution: static creates separate function for each .cpp file, increasing code size.

Cause 2: Global Variable Definition in Header

Below is an implementation example using C++. Import the necessary modules. Understand the role of each part while examining the code.

// ❌ config.h
int maxConnections = 100;  // Definition in header

// main.cpp
#include "config.h"

// server.cpp
#include "config.h"

// Link error: multiple definition of 'maxConnections'

Solution 1: Use extern (Recommended)

Below is an implementation example using C++. Try running the code directly to check its operation.

// ✅ config.h
extern int maxConnections;  // Declaration only

// config.cpp
int maxConnections = 100;  // Definition (in one place only)

Solution 2: inline Variable (C++17)

Here is a simple C++ code example. Try running the code directly to check its operation.

// ✅ config.h (C++17)
inline int maxConnections = 100;  // inline variable

Summary

Key Points

  1. ODR: One Definition Rule - define at most once
  2. Header files: Declaration only, definition in .cpp
  3. inline: Allows multiple definitions
  4. extern: Declaration, definition elsewhere
  5. static: Separate copy per file (not recommended)

When to Use

Use inline when:

  • Small functions in headers
  • Template functions
  • constexpr functions

Use extern when:

  • Global variables
  • Sharing variables across files

Don’t use:

  • Regular function definitions in headers
  • Global variable definitions in headers

Best Practices

  • ✅ Separate declaration and definition
  • ✅ Use inline for small functions
  • ✅ Use extern for global variables
  • ❌ Don’t define functions in headers
  • ❌ Don’t use static for functions (increases code size)

Master ODR for clean C++ code! 🚀