Different implementations of built-in functions in different translation units

The C ++ standard talks about ODR as it relates to inline functions (emphasis mine):

3.2 One rule of definition

3 Each program must contain exactly one definition of each non-built-in function or variable that is odr-used in that program; no diagnostics required. The definition can appear explicitly in the program, it can be found in the standard or user-defined library, or (if needed) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function must be defined in every translation unit in which it is used .

It doesn't say anything about whether built-in 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 with g++ 4.7.3

.

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

+1


source to share


3 answers


ISO C ++ 2003 § 3.2 clause 5 says

There can be multiple class type definitions (section 9), an enumeration type (7.2), an inline function with external linkage (7.1.2), a class template (section 14), a non-static function template (14.5.5), a static data member of a class template ( 14.5.1.3), a member function of a class template (14.5.1.1), or a template template for which some template parameters are not specified (14.7, 14.5.4) in the program, provided that each definition appears in a different translation unit and provided that definitions meet the following requirements: Cops. Given such an object named D defined in more than one translation unit, then

  • each definition of D must consist of the same sequence of tokens
  • (requirements follow)

...

If the definitions of D do not satisfy these requirements, then the behavior is undefined.



Thus, no, non-equivalent definitions are illegal. Since the behavior is undefined, the compiler can pretty much do anything, including choosing its favorite implementation and ignoring others.

+9


source


You need to finish reading this subparagraph. §3.2 [basic.def.odr] / p6 documents the requirements for several definitions of externally linked built-in functions. The entire list of requirements with half a dozen items takes up an entire page, but basically boils down to "they must have exactly the same sequence of tokens and mean exactly the same."



In your case, multiple definitions foo

do not even satisfy the first requirement - that the definitions consist of the same sequence of tokens. Undefined.

+4


source


There is no explicit instruction in the standard that says that an inline function must have one and only one implementation object. Of course, in production code, you need to make sure there is only one organ. Imagine a debugging / maintenance fiasco if you need to work with code like the one you show in the example!

This is obviously not code that you would run in production; I hear you wondering what language.

Since the standard is not explicit, this leads to a gray area and compilers will do whatever they want. In fact, Stroustrup himself wrote in 1994 in "Design and Evolution of C ++" that most compilers do not check for this, and this situation has not improved to this day!

-1


source







All Articles