Different implementations of inline functions in different translation units

↘锁芯ラ 提交于 2020-01-02 21:56:12

问题


The C++ standard says this about ODR, as it applies to inline functions (emphasis mine):

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.

It doesn't say anything about whether the inline functions can have different implementations in different translation units. I tried the following:

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;
}

I was expecting to see the following output:

Foo_1
Foo_2

Instead, I saw:

Foo_1
Foo_1

I tested it using g++ 4.7.3.

Is g++ correct in choosing to pick one of the inline implementations? Is it not possible to provide different implementations of inline functions in different translation units?


回答1:


ISO C++ 2003 § 3.2 paragraph 5 says

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.

So, no, non-equivalent definitions are illegal. Since the behaviour is undefined the compiler is pretty much free to do anything, including picking his favorite implementation and ignoring others.




回答2:


You need to finish reading that subclause. §3.2 [basic.def.odr]/p6 documents the requirements for multiple definitions of inline functions with external linkage. The whole list of requirements with half a dozen items occupies a whole page, but basically boils down to "they must have exactly the same sequence of tokens and mean exactly the same thing".

In your case the multiple definitions of foo don't even satisfy the first requirement - that the definitions consist of the same sequence of tokens. Undefined behavior results.




回答3:


There is no explicit statement in the standard that says that an inline function should have one, and only one implementation body. Of course, in production code, you have to make sure there's only one body .. imagine the debugging/maintenance fiasco if you have to work with code like the one you give in example !

This is obviously not code you would run in production ; I hear you, you are curious about the language.

Because the standard is not explicit, this leads to a gray area and compilers do whatever they want. Actually, Stroustrup himself wrote in 1994 in "Design & Evolution of C++" that most compilers don't check for this , and this situation hasn't improved to this day !



来源:https://stackoverflow.com/questions/26241023/different-implementations-of-inline-functions-in-different-translation-units

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!