본문으로 건너뛰기 C++ One Definition Rule : Multiple Definitions, inline,

C++ One Definition Rule : Multiple Definitions, inline,

C++ One Definition Rule : Multiple Definitions, inline,

이 글의 핵심

The ODR requires a single definition across the program for variables and functions, with exceptions for inline, templates, and C++17 inline variables. Avoid multiple definition link errors.

Introduction

1. Basic ODR rules

Variables

// ❌ ODR violation
// file1.cpp
int globalVar = 10;
// file2.cpp
int globalVar = 20;  // multiple definitions
// ✅ Correct pattern
// header.h
extern int globalVar;  // declaration
// file1.cpp
int globalVar = 10;   // single definition
// file2.cpp
#include "header.h"   // declaration only

Functions

// ❌ Two definitions of the same function
// file1.cpp
void func() { std::cout << "file1\n"; }
// file2.cpp
void func() { std::cout << "file2\n"; }
// ✅ Declaration in header, single definition in one .cpp
// header.h
void func();
// file1.cpp
void func() { std::cout << "implementation\n"; }

2. ODR exceptions

inline functions

// utils.h
inline int add(int a, int b) {
    return a + b;
}
// file1.cpp
#include "utils.h"
// file2.cpp
#include "utils.h"  // OK if identical

Key point: inline definitions may appear in multiple TUs if token-identical.

Templates

Templates are typically defined in headers and instantiated in multiple TUs—ODR allows this under the usual rules for templates.

constexpr / inline variables (C++17)

inline constexpr int MAX = 100;  // single definition across TUs (C++17 inline variable)

3. Practical examples

Example 1: Global configuration

// config.h
#ifndef CONFIG_H
#define CONFIG_H
extern int maxConnections;
extern const char* appName;
inline int maxRetries = 3;
#endif
// config.cpp
#include "config.h"
int maxConnections = 100;
const char* appName = "MyApp";

Example 2: Class in header, members in .cpp

Class definitions in headers must be identical in every TU that sees them—normally one shared header.

Example 3: static data members

Pre-C++17: define non-inline static data members in one .cpp. C++17 allows inline static members in-class.

4. Common problems

Problem 1: Non-inline function definitions in headers

Put non-inline definitions in a single .cpp, or mark small functions inline in the header.

Problem 2: Different definitions of the same type

If two TUs define struct Data differently, ODR is violated and behavior is undefined even if it “compiles.” Fix: define shared types in one header included everywhere.

Problem 3: Anonymous namespaces in headers

Each TU gets its own anonymous namespace—avoid putting headers in headers that should share state.

Problem 4: constexpr variables before C++17

Prefer inline constexpr in C++17+ for header-defined constants with a single-definition guarantee.

5. ODR-friendly patterns

Header / source split

Declarations and inline/template in headers; non-inline function bodies in one .cpp.

Logging helpers as inline in headers

Short inline void log(...) in headers is a common pattern.

6. Library-style example

Singleton or logger patterns: declare static members appropriately; define inline static in-class when possible (C++17).

7. Detecting violations

  • Linker: multiple definition of ...
  • nm across .o files for duplicate strong symbols
  • Warnings: -Wall -Wextra

Summary

  1. ODR — generally one definition.
  2. Variables — one definition; extern in headers for declarations.
  3. Functions — one definition unless inline/template rules apply.
  4. Classes — identical definitions in every TU.
  5. Exceptionsinline, templates, inline variables (C++17).

Quick reference

ItemHeaderSource
Variable declarationextern int var;int var = 0;
Function declarationvoid f();void f() {}
Class definitionclass C {};
inline functioninline void f() {}
Templatefull definition in header
Next: Extern linkage, Header files, Function overloading.


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. The ODR requires a single definition across the program for variables and functions, with exceptions for inline.

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, ODR, one definition rule, linking, inline.