C ++ множественное определение структуры - PullRequest
1 голос
/ 07 июля 2019

У меня есть заголовок util.hpp, содержащий простую структуру:

// util.hpp

struct Point {
  float x;
  float y;
};

Два файла cpp, давайте назовем их a.cpp и b.cpp, оба включают 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() {
  // ...
}

Когда я компилирую a.cpp и b.cpp по отдельности, а затем связываю их вместе, я не получаю ошибок.

Почему это так?Поскольку я включаю util.hpp в оба файла, разве у нас не будет двойного определения struct Point?Например, когда я добавляю определение переменной в util.hpp следующим образом:

// util.hpp

struct Point {
  float x;
  float y;
};

// New variable
int foo;

, я получаю следующую ошибку при линковке:

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

, что имеет смысл для меня, но почему нетне происходит ли та же ошибка для структуры?

Ответы [ 2 ]

4 голосов
/ 07 июля 2019

bo :(. Bss + 0x0): множественное определение `foo '

, имеющее

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

каждый раз, когда вы включаете util.hpp вы снова определяете глобальную переменную foo, в результате чего ваша ошибка

в заголовочном файле просто объявляет it (extern int foo;)и определите его в одном исходном файле

Для struct Point такой же проблемы нет, потому что это определение типа, а не определение глобальной переменной

3 голосов
/ 07 июля 2019

Определение типа (struct, union, class, enum) является всего лишь своего рода «планом» для компилятора, как размещать определенные вещи в памяти, но не вызывать генерациюкод или символы сами по себе.

В C ++ вы также можете иметь функции-члены и операторы и статические переменные-члены , однако они технически не являются частью структуры /класс, но поставляется с структурой / классом, и поэтому вы можете глобально определить их только один раз.

И точно так же, как определение глобальной переменной foo, которое у вас есть, это не работаетесли сделано в файле, включенном несколько раз.Но вы можете безопасно объявить их несколько раз.

...