我违反一个定义规则与以下程序?匿名命名空间和一个定义规则
// 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()
的主体是相同的。
我认为这清楚地说明了为什么在头文件中使用匿名命名空间或静态函数会带来麻烦:) –