extern变量导致多个定义错误

时间:2013-01-26 06:36:11

标签: c++ extern multiple-definition-error

我一直在尝试使用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
  • 我如何定义'extern'变量并在同一个文件中初始化它(因为它稍后在同一个文件中使用)

1 个答案:

答案 0 :(得分:8)

  

为什么在定义后卫存在时lib.h多次被包含

您需要删除定义:

bool initialized = false;

并将其放在一个且只有一个源文件中。

包含防护措施可防止相同的头文件多次包含在同一 translation unit(TU) 中,而不是在不同的翻译单元中。 您可以在头文件中定义变量initialized,该变量包含在不同的翻译单元中,然后每个TU都有一个名为initialized的符号,用于打破 one definition rule

  

我如何定义'extern'变量并在同一个文件中初始化它(因为它稍后在同一个文件中使用)

如果您希望变量在同一个文件中使用,为什么要将其变为extern?如果要在不同的TU之间共享相同的变量,则需要使用extern 如果您只需要在单一TU中在全球范围内使用它,您应该简单地将其放在 unnamed namespace 中。