C++ 标准是这样描述 ODR 的,因为它适用于内联函数(强调我的):
3.2 One definition rule
3 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.
它没有说明内联函数是否可以在不同的翻译单元中有不同的实现。我尝试了以下方法:
test-1.cc
#include <iostream>
inline std::ostream& foo(std::ostream& os)
{
return os << "Foo_1";
}
void test_1()
{
foo(std::cout) << std::endl;
}
test-2.cc
#include <iostream>
inline std::ostream& foo(std::ostream& os)
{
return os << "Foo_2";
}
void test_2()
{
foo(std::cout) << std::endl;
}
main.cc
extern void test_1();
extern void test_2();
int main()
{
test_1();
test_2();
return 0;
}
我期待看到以下输出:
Foo_1
Foo_2
相反,我看到了:
Foo_1
Foo_1
我使用 g++ 4.7.3
对其进行了测试。
g++ 选择其中一种内联实现是否正确?难道不能在不同的翻译单元中提供不同的内联函数实现吗?
最佳答案
ISO C++ 2003 § 3.2 第 5 段说
There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template special- ization for which some template parameters are not specified (14.7, 14.5.4) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following require- ments. Given such an entity named D defined in more than one translation unit, then
- each definition of D shall consist of the same sequence of tokens
- (more requirements follow)
...
If the definitions of D do not satisfy these requirements, then the behavior is undefined.
所以,不,非等效定义是非法的。由于行为未定义,编译器几乎可以自由地做任何事情,包括选择他最喜欢的实现并忽略其他实现。
关于c++ - 不同翻译单元内联函数的不同实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26241023/