我違反一個定義規則與以下程序?匿名命名空間和一個定義規則
// foo.hpp
#ifndef FOO_HPP_
#define FOO_HPP_
namespace {
inline int foo() {
return 1;
}
}
inline int bar() {
return foo();
}
#endif
//EOF
和
// m1.cpp
#include "foo.hpp"
int m1() {
return bar();
}
//EOF
和
// m2.cpp
#include "foo.hpp"
int m2() {
return bar();
}
//EOF
最後
// main.cpp
#include <iostream>
int m1();
int m2();
int main(int, const char* [])
{
int i = m1();
int j = m2();
std::cout << (i+j) << std::endl;
return 0;
}
// EOF
在上面,注意foo()
是在匿名的命名空間中定義,因此,我希望每翻譯單元m1.cpp
和m2.cpp
將獲得它自己的版本,所以沒有違反ODR。另一方面,bar()
只是一個簡單的舊內聯函數,它恰好會調用2個不同的foo
s。所以它違反了ODR,對吧?
更新: 以前我曾在不同的包括foo.hpp
一改之前定義的宏它返回的值,每個m1
和m2
的的foo
定義宏。 (在前面的例子中,g++
會生成一個二進制數,輸出(i+j)
,而不是您期望的值。)但實際上,該程序違反了ODR,即使foo()
的主體是相同的。
我認爲這清楚地說明了爲什麼在頭文件中使用匿名命名空間或靜態函數會帶來麻煩:) –