C ++ include various header files with the same class implementation in multiple source files

for example

hijras

class Dummy { public: Dummy() { std::cout << "ah" << std::endl; } }; 

bh

 class Dummy { public: Dummy() { std::cout << "bh" << std::endl; } }; 

c.cc

 #include "ah" void test() { Dummy a; } 

d.cc

 #include "bh" int main() { Dummy a; return 0; } 

Then compile the source files with the command

 g++ d.cc c.cc 

output

 bh 

but with the team

 g++ c.cc d.cc 

output

 ah 

My question is why there is no multiple definition error and why the output depends on the compilation order?

+7
c ++ compilation g ++ one-definition-rule
source share
2 answers

Your program has undefined behavior. To summarize the C ++ standard, here is [basic.def.odr / 6] with an emphasis:

A class can have several definitions of the type [,]. programs, provided that each definition appears in a different one and provided that the definitions satisfy the following requirements. Given such an entity D defined in more than one translation unit, then

  • each definition of D must consist of the same sequence of tokens ; and

  • [...]

[...] If the definitions of D satisfy all these requirements, then the behavior is similar to the fact that there is one definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.

So, you are observing two different behaviors. Absolutely acceptable, given that the language does not contain restrictions on the behavior that you should even see. You violated the contract, so there are no guarantees.

Now, from a practical point of view, what you see is just GCC, working on the above contract. It is assumed that you will not violate it (even if you do) and simply ignore any subsequent redefinitions of Dummy and / or its members. The first "wins."

+8
source share

The compiler does not detect a multiple-definition error, since c.cc and d.cc are separate translation units. They are processed separately from each other; each has exactly one definition of the Dummy::Dummy constructor.

The connector does not detect a multiple definition error, because the definition of the Dummy::Dummy constructor from the header is treated as an inline definition. The language allows a built-in definition in each translation unit, if they are all identical. Typically, the reason these definitions are identical is because they are all taken from the same header file, but the standard requires that the definitions be identical, even if they come from different files.

When your program violates this rule, its behavior is undefined. This is why your program behaves differently depending on the seemingly unrelated act of changing the order of translation units during the translation.

+3
source share

All Articles