我是否违反了One Definition Rule并使用以下程序?
// 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
。所以它违反了ODR,对吧?
更新的
以前我在foo
的定义中使用宏来更改它返回的值,m1
和m2
中的每一个都在包含foo.hpp
之前对宏进行了不同的定义。 (并且使用前面的示例,g++
将生成一个二进制文件,输出(i+j)
的值不是您期望的值。)但实际上这个程序违反了ODR,即使是foo()
完全相同。
答案 0 :(得分:8)
这确实违反了ODR。请参阅3.2 / 5,其中讨论了外部内联函数(bar
):
在每个D的定义中,相应的名字,按照查找 3.4,应指D中定义的实体,或指同一实体......
在这种情况下,bar
引用了两个不同版本的foo
,因此违反了规则。
答案 1 :(得分:6)
是的,bar()
的这个定义确实违反了一个定义规则。您正在创建多个定义,每个定义都调用一个名为foo()
的不同函数。
正如你所说,即使foo()
的所有版本都相同,这也是违规行为,因为它们仍然是不同的功能。