C++ Multiple Definition of Struct
Asked Answered
S

2

7

I have header util.hpp containing a simple struct:

// util.hpp

struct Point {
  float x;
  float y;
};

Two cpp files, let's call them a.cpp and b.cpp, both include util.hpp:

// a.cpp

#include "util.hpp"

void funcA(float _x, float _y) {
  Point p;
  p.x = _x;
  p.y = _y;
  // ...
}
// b.cpp

#include "util.hpp"

void funcB(float _x, float _y) {
  Point p;
  p.x = _x;
  p.y = _y;
  // ...
}

int main() {
  // ...
}

When I compile a.cpp and b.cpp individually and then link them together I get no errors.

Why is that? Since I include util.hpp in both files, wouldn't we have a double definition of struct Point? When I for example add a variable definition to util.hpp like this:

// util.hpp

struct Point {
  float x;
  float y;
};

// New variable
int foo;

I get the following error when linking:

g++ a.o b.o -o test -O0
b.o:(.bss+0x0): multiple definition of `foo'
a.o:(.bss+0x0): first defined here

which makes sense to me, but why doesn't the same error occur for the struct?

Szechwan answered 7/7, 2019 at 13:20 Comment(3)
each time you include util.hpp you define the global variable fooEvangelist
@Evangelist Yes you are right, "int foo;" is actually a definition, just changed the wording from "declaration" to "definition"Szechwan
Finaly I also did an answer to say that and moreEvangelist
E
6

b.o:(.bss+0x0): multiple definition of `foo'

having

// util.hpp
...
// New variable
int foo;

each time you include util.hpp you define again the global variable foo, producing your error

in the header file just declare it (extern int foo;) and define it on one source file

There is not the same problem for the struct Point because this is a type definition, not a global variable definition

Evangelist answered 7/7, 2019 at 13:26 Comment(0)
F
5

A type definition (struct, union, class, enum) is just kind of a "blueprint" for the compiler how to lay out certain things in memory but don't cause the generation of code or symbols on their own.

In C++ you can also have member functions and operators and static member variables, however these are technically not part of the struct/class but come with the struct/class and as such you can globally define them only once.

And just like that global variable definition of foo you have there this doesn't work if done in a file included multiple times. But you can safely declare them multiple times.

Fee answered 7/7, 2019 at 13:24 Comment(2)
So a multiple type definition is allowed? Does the linker recognize that it's the same struct in both object files?Szechwan
@Kittion: No, multiple type definitions are not allowed inside a single compilation unit. What happens is, that type definitions by themself do not emit anything. And because there's nothing emitted there's nothing for the linker to complain about.Fee

© 2022 - 2024 — McMap. All rights reserved.