переменная extern вызывает ошибку множественного определения

Я пытался использовать extern для того, чтобы использовать переменную, которая была ранее определена.

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

Я написал минимизированную версию кода для этого вопроса. У меня четыре файла

lib.h

#ifndef LIB_H
#define LIB_H

#include <iostream>

namespace lib {

extern bool initialized;

bool initialized = false;

static void isInit(char* parent) {
std::cout << "Library for [" << parent << "] initialized? " << (::lib::initialized ? "yes" : "no") << "\n";
}
} // namespace lib
#endif

vehicle.h

#ifndef _VEHICLE_H
#define _VEHICLE_H
#include <string>

class Vehicle {
public:
Vehicle(const std::string& manufacturer,
const std::string& model,
int year);
std::string manufacturer;
std::string model;
int year;
};
#endif

Ниже приведена реализация файла vehicle.h с именем vehicle.cpp.

#include "vehicle.h"
#include "lib.h"
Vehicle::Vehicle(const std::string& manufacturer,
const std::string& model,
int year) :
manufacturer(manufacturer),
model(model),
year(year) {
::lib::isInit("Vehicle");
}

main.cpp

#include "vehicle.h"
#include "lib.h"
int main(int argc, char** argv) {

::lib::isInit("main");

::lib::initialized = true;

::lib::isInit("main");

Vehicle vehicle("Toyota", "Corolla", 2013);

return 0;
}

Я использую g ++

g++ -Wno-write-strings main.cpp vehicle.cpp -o bin/main.cpp.bin

Я получаю следующие ошибки:

/tmp/cclVpsgT.o:(.bss+0x0): multiple definition of `lib::initialized'
/tmp/ccmJKImL.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status

Я проверил вывод:

g++ -Wno-write-strings main.cpp vehicle.cpp -E

множественное определение происходит каждый раз, когда включен lib.h.

Мои вопросы:

  • Почему lib.h включен несколько раз, когда есть определение guard
  • Как бы определить переменную ‘extern’ и инициализировать ее в том же файле (поскольку она будет использоваться в том же файле позже)

5

Решение

Почему lib.h включены несколько раз, когда определить охранник есть

Вам необходимо удалить определение:

bool initialized = false;

И поместите его в один и только один исходный файл.

Защитные щитки предотвращают включение одного и того же заголовочного файла более одного раза в один и тот же переводческий блок (ТУ) не в разных единицах перевода.
Вы определяете переменную initialized в заголовочном файле, который включается в различные единицы перевода, а затем каждый TU имеет символ с именем initialized который ломает одно определение правила.

Как бы определить переменную ‘extern’ и инициализировать ее в том же файле (поскольку она будет использоваться в том же файле позже)

Если вы хотите, чтобы переменная использовалась в том же файле, зачем делать это extern? Вам нужно использовать extern когда вы хотите использовать одну и ту же переменную в разных TU.
Если вам нужно использовать его в глобальном масштабе только в одном TU, вы должны просто поместить его в безымянное пространство имен.

8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]