...
Code Block | ||||
---|---|---|---|---|
| ||||
// a.h #ifndef A_HEADER_FILE #define A_HEADER_FILE namespace { int v; } #endif // A_HEADER_FILE // a.cpp #include "a.h" #include <iostream> void f() { std::cout << "f(): " << v << std::endl; v = 42; // ... } // b.cpp #include "a.h" #include <iostream> void g() { std::cout << "g(): " << v << std::endl; v = 100; } int main() { extern void f(); f(); // Prints v, sets it to 42 g(); // Prints v, sets it to 100 f(); g(); } |
When executed, this program will print:
...
In this compliant solution, v
is defined in only one translation unit, but is externally visible to all translation units and can be accessed from the inline get_v()
function, resulting in the expected behavior:
Code Block | ||||
---|---|---|---|---|
| ||||
// a.h #ifndef A_HEADER_FILE #define A_HEADER_FILE extern int v; inline int get_v() { return v; } #endif // A_HEADER_FILE // a.cpp #include "a.h" #include <iostream> int v; // ExternallyDefinition usedof by get_v(); intglobal variable v; void f() { int i = get_v()std::cout << "f(): " << v << std::endl; v = 42; // ... } // b.cpp #include "a.h" #include <iostream> void g() { std::cout << "g(): " << v << std::endl; int i = get_v(); // ... }v = 100; } int main() { extern void f(); f(); // Prints v, sets it to 42 g(); // Prints v, sets it to 100 f(); // Prints v, sets it back to 42 g(); // Prints v, sets it back to 100 } |
When executed, this program will print:
Code Block |
---|
f(): 0
g(): 42
f(): 100
g(): 42 |
Risk Assessment
Defining an unnamed namespace within a header file can cause data integrity violations and performance problems, but is unlikely to go unnoticed with sufficient testing. One Definition Rule violations result in undefined behavior.
...