2015-11-27 121 views
0

这是我的头文件。多个定义,即使我使用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

你在这里显示的没有变量'DAYS'的任何定义。所以很难知道问题是什么,因为你没有显示任何可能导致问题的东西。不,你不应该编译P6.h.这不是它的工作原理。 – Art

+1

“...这是外部的,并在每个单独声明和初始化”。努力理解你的英语,但这是否意味着你在多个.c文件中定义了这个变量?如果是这样,那就是错误的原因。 – Lundin

+0

使用原型声明,而不是旧的K&R风格。自25年以来它们已经过时。 – Olaf

回答

0

为了帮助您理解,以下是@ FUZxxl的答案的延伸,这是正确的。如果你在你的编译单元以下(编译单元是.c的源文件以及所有包含.h文件):

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

那么DAYS第二个声明将覆盖这说明它是extern第一次申报。因此,变量现在不再是extern,如果您在多个源文件中执行此操作,则现在会有多个定义,并且链接器会发出抱怨。

如果你必须初始化DAYS那么你可以做,在一个步伐,在主文件中优选的。

+0

谢谢你的工作,我忘了或根本没有意识到,当你初始化一个外部变量的主要初始化是通过其余的C文件进行。 – codehelp4

1

每个单独初始化。

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

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

+0

你是什么意思?我认为初始化变量是extern的工作原理。我在这里看到了另一个问题的答案,其中有人说要在头文件中写入变量,如extern int var或int var,告诉提问他们的问题的人不要在头文件中进行初始化。这听起来像你告诉我在标题中初始化外部变量,但会导致警告。 – codehelp4

+0

@ codehelp4不!我告诉你只能在一个源文件中初始化变量。从你的问题看来,你似乎尝试在多个源文件中初始化相同的变量。 – fuz

1

首先,从在GCC的makefile. -o选项的最后一个命令删除P6.h用于编译和链接多个源files.So,这没有任何意义。

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