One Definition Rule
Főnév
One Definition Rule (tsz. One Definition Rules)
- (informatika) A One Definition Rule (röviden: ODR) a C++ nyelv egyik alapvető szabálya, amely kimondja:
Egy programon belül **minden típusnak, függvénynek, változónak vagy inline függvénynek pontosan egy definitív definíciója lehet – még akkor is, ha több fordítási egységből (translation unit) áll.
Ez a szabály garantálja a típusbiztonságot, az összeállítás helyességét, és azt, hogy a program deterministán viselkedjen.
🧠 Röviden: mi a definíció?
A deklaráció csak kijelenti, hogy létezik valami:
extern int x; // deklaráció – nincs tárhely
int f(); // függvény deklaráció
A definíció létre is hozza az entitást:
int x = 5; // definíció – tárhely is foglalva
int f() { ... } // függvénydefiníció
Az ODR azt mondja: csak egy definíció lehet, különben undefined behavior (UB) keletkezik.
📦 Mire vonatkozik az ODR?
Az ODR különböző entitásokra vonatkozik:
| Entitás | ODR érvényes? | Megjegyzés |
|---|---|---|
class vagy struct |
✅ Igen | Csak egy definitív definíció lehet, de több deklaráció |
inline függvény |
✅ Igen | Többször előfordulhat, de bitazonos kell legyen |
template definíció |
✅ Igen | Fordítási egységekben azonosnak kell lennie |
constexpr funkció |
✅ Igen | Ugyanaz a szabály, mint inline-nál |
const globális változó |
✅ Igen | const globálisként csak a translation unit-on belül látható, ha nincs extern |
non-const globális változó |
✅ Igen | Csak egyszer definiálható az egész programban |
🔧 Példa ODR megsértésére
// file1.cpp
int x = 5;
// file2.cpp
int x = 10;
// → undefined behavior
Ha file1.o és file2.o össze van linkelve, az x változónak két különböző definíciója van – ez megsérti az ODR-t.
✅ Hogyan lehet helyesen megosztani?
Használj deklarációt a header fájlban, és definíciót egy .cpp fájlban:
// x.h
extern int x;
// x.cpp
int x = 5;
// main.cpp
#include "x.h"
Így az x változónak csak egy definíciója lesz (x.cpp), és több deklarációja (extern int x;).
🏗️ ODR osztályokra
// myclass.h
struct MyClass {
void hello();
};
// myclass.cpp
#include "myclass.h"
void MyClass::hello() {
std::cout << "Hello!\n";
}
Ez megfelel az ODR-nek: csak egy osztálydefiníció, és külön implementáció.
🚨 Mikor sérül az ODR?
1. Többszörösen beillesztett definíciók
// myheader.h
int global = 5;
// main.cpp
#include "myheader.h"
#include "other.cpp"
// other.cpp
#include "myheader.h"
Itt global kétszer lesz definiálva: megsérti az ODR-t.
👉 Megoldás: használj extern kulcsszót headerben, és tényleges definíciót .cpp-ben.
🧪 Inline függvények és ODR
Az inline függvények többször definiálhatók, de a definíciójuknak pontosan azonosnak kell lennie minden fordítási egységben.
// utils.h
inline int square(int x) {
return x * x;
}
Ez megengedett, de minden .cpp fájlban azonos kód kell legyen.
Ha eltér:
// file1.cpp
inline int square(int x) { return x * x; }
// file2.cpp
inline int square(int x) { return x + x; }
// → undefined behavior
🧱 Template-ek és ODR
A sablonokat (template<class T>) a fordító példányosítja minden típusra. Ezek is ODR-nek vannak alávetve: azonos sablonpéldány ugyanolyan kódot kell adjon minden .cpp-ben.
Ha egy template<class T> osztály vagy függvény két fájlban különböző implementációt kap: sértés.
🎯 C++11 és újabb: inline változók
// config.h
inline int version = 1;
Ez C++17-től megengedett, és nem sérti az ODR-t – minden fordítási egység láthatja.
🧭 Összegzés
| Fogalom | Jelentés |
|---|---|
| ODR (One Definition Rule) | Minden entitásnak pontosan egy definíciója lehet |
| Többszörös deklaráció | ✅ megengedett |
| Többszörös definíció | ❌ tilos, kivéve inline, template, constexpr stb. |
| Violáció eredménye | Undefined behavior (UB) |
| Megoldás | extern + .cpp definíció |
| C++17 újdonság | inline változók |
🧠 Zárógondolat
Az ODR a C++ linkelési modellének alapja. Ha megsértjük, nincs garantált működés – a program fordulhat, de futás közben hibásan viselkedik. Ezért fontos az extern, a header–.cpp szétválasztás, az inline és a #pragma once vagy include guard tudatos használata.
- One Definition Rule - Szótár.net (en-hu)
- One Definition Rule - Sztaki (en-hu)
- One Definition Rule - Merriam–Webster
- One Definition Rule - Cambridge
- One Definition Rule - WordNet
- One Definition Rule - Яндекс (en-ru)
- One Definition Rule - Google (en-hu)
- One Definition Rule - Wikidata
- One Definition Rule - Wikipédia (angol)