Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ include different header files with same implementation of class in multiple source files

For example

a.h

class Dummy {
public:
  Dummy() { std::cout << "a.h" << std::endl; }
};

b.h

class Dummy {
public:
  Dummy() { std::cout << "b.h" << std::endl; }
};

c.cc

#include "a.h"

void test() {
  Dummy a;
}

d.cc

#include "b.h"

int main() {
  Dummy a;
  return 0;
}

Then compile source files with command

g++ d.cc c.cc

output is

b.h

but with command

g++ c.cc d.cc

output is

a.h

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

like image 608
Scy Avatar asked Dec 25 '17 11:12

Scy


People also ask

How do I include a header file in multiple sources?

Typically this is done by having a . h or . cpp file with all your #include s in; you then #include this file first in each file (or use the idea of a 'forced include': /Fi in msvc, -include with gcc).

Can we use same header files in multiple C programs are not?

Summing up: it is not redundant to include the same files in different C files -- it is formally required. (Afterwards, you link object files, which are just smaller programs, into a larger final program.

Can you have multiple header files in C?

Including Multiple Header Files:You can use various header files in a program.


1 Answers

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

There can be more than one definition of a class type, [...] in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. 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; and

  • [...]

[...] If the definitions of D satisfy all these requirements, then the behavior is as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.

So you observe two different behaviors. Perfectly acceptable, given the language places no restrictions on what behavior you should even see. You violated the contract, so there are no guarantees.

Now, from a practical standpoint, what you see happen is just GCC operating under the above contract. It assumes you wouldn't violate it (even if you do), and just ignores any subsequent re-definitions of Dummy and/or its members. The first one "wins out".

like image 84
StoryTeller - Unslander Monica Avatar answered Oct 11 '22 01:10

StoryTeller - Unslander Monica