Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Completed last CS

...

Code Block
bgColor#FFcccc
langcpp
// 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
bgColor#ccccff
langcpp
// 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.

...