多个定义,即使我使用extern并包含警卫

时间:2015-11-27 07:33:57

标签: c makefile global-variables extern

这是我的头文件。

#ifndef P6_H
#define P6_H



#include <stdio.h>
void FoundationC();      
void StructureC();       
void PlumbingC();        
void ElectricC();        
void HVACC();            
void SheatingC();        


extern int DAYS;          

#endif

我使用makefile进行所有编译。它能够编译单个.o文件文件,但是当它尝试将它们转换成单个可执行文件时,它表示变量DAYS有多个定义,即使它是extern并在每个单独声明和初始化。我以前让这个工作,但无法弄清楚为什么它现在不工作。 哦,这是我的makefile代码

all:

    gcc -c P6.c
    gcc -c foundations.c
    gcc -c structure.c
    gcc -c plumbing.c
    gcc -c electric.c
    gcc -c hvac.c
    gcc -c sheating.c
    gcc  P6.h P6.o foundations.o structure.o plumbing.o electric.o hvac.o sheating.o -o P6

我意识到P6.h可能不必包含在命令中,但包含警卫应该使它不重要吗?

此外,我很抱歉,如果这个问题是一个骗局,但我之前做过寻找答案,这个问题让我在个人层面上疯狂,尽管这是学校的事。

以下是我得到的错误。

gcc -c P6.c
gcc -c foundations.c
gcc -c structure.c
gcc -c plumbing.c
gcc -c electric.c
gcc -c hvac.c
gcc -c sheating.c
gcc  P6.h P6.o foundations.o structure.o plumbing.o electric.o hvac.o sheating.o -o P6
structure.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
plumbing.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
electric.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
hvac.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
sheating.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

3 个答案:

答案 0 :(得分:1)

  

逐个初始化。

你的错误。如果您在不同的翻译单元中初始化相同的变量,您认为会发生什么?如果这些使用不同的值,您认为会发生什么?

您只能在程序中定义一次变量,但多个声明都可以。除了一个翻译单元外,请删除DAYS的定义以解决此问题。

答案 1 :(得分:1)

首先,从makefile中的最后一个命令中删除P6.h.-g选项用于编译和链接多个源文件。所以,这没有任何意义。

其次将DAYS定义为&#34; int DAYS&#34;在.c文件中,您可以在相应的.h文件中将其声明为extern,并在所有其他源.c文件中包含此.h文件。这将解决此多个定义问题。 示例:将日期定义为&#34; int DAYS&#34;在A.c中,你将其声明为&#34; extern int DAYS&#34;在A.h.Now,您可以将此A.h包含在其他源文件中,如B.c,C.c,D.c等。

答案 2 :(得分:1)

为了帮助您理解,以下是@ FUZxxl答案的扩展,这是正确的。如果您的编译单元中有以下内容(编译单元是.c源文件加上所有包含的.h文件):

extern int DAYS;
...
int DAYS = 1;

然后DAYS的第二个声明会覆盖第一个声明它是extern的声明。因此,变量现在不再是extern,如果您在多个源文件中执行此操作,那么现在您有多个定义并且链接器会抱怨。

如果您必须初始化DAYS,那么您可以在一个地方执行此操作,最好是在主文件中。