为什么头文件中的全局变量会导致链接错误?

时间:2013-07-11 12:11:38

标签: c include-guards

我总是得到以下错误,即使我已将include guard放在头文件中。

duplicate symbol _Bittorrent in:
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/main.o
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/Handshake.o
duplicate symbol _eight_byte in:
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/main.o
    /Users/tracking/Library/Developer/Xcode/DerivedData/SHT-giuwkwyqonghabcqbvbwpucmavvg/Build/Intermediates/SHT.build/Debug/SHT.build/Objects-normal/x86_64/Handshake.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这是.h头文件,.c文件和main.c

的main.c

#include "Handshake.h"
int main(int argc, char** argv)
{
    // some code.
    return 0;
}

Handshake.h

#ifndef SHT_Handshake_h
#define SHT_Handshake_h

const char    *Bittorrent     =   "BitTorrent protocol";
const char    eight_byte[8]   =   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

#endif

Handshake.c

#include "Handshake.h"


int Send_fisrt_Handshake(download_connection *pPeer, Handshake *necessary_info)
{
    //some statements
    return 1;
}

void Set_Handshake_information(TorrentFile* pArg, Handshake *pYours)
{

    //some statements

}

但是,如果我从头文件中删除了全局变量,这些代码就会成功编译 我不明白为什么。有人能解释为什么吗?提前谢谢。

5 个答案:

答案 0 :(得分:6)

这样的行
const char    *Bittorrent     =   "BitTorrent protocol";
const char    eight_byte[8]   =   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

定义全局变量,无论代码是在头文件中还是在a .c中直接(#include只是文本插入标题的内容)。 相反,您应该在exaclty一个源文件中定义并更改标题以提供extern声明:

extern const char *Bittorrent;
extern const char *eight_byte;

然后可以编译使用thes变量的所有源代码,但链接器仅将变量赋值一次。

答案 1 :(得分:2)

因为定义头文件中的变量。然后,包含头文件的所有源文件都将定义这些变量。

您可以使用extern关键字声明变量:

extern const char    *Bittorrent;
extern const char    eight_byte[8];

然后在一个源文件中定义变量。

或者您可以将变量定义为static,这会将其范围限制为翻译单位(即源文件):

static const char    *Bittorrent     =   "BitTorrent protocol";
static const char    eight_byte[8]   =   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

这与C ++不同,const也暗示static

答案 2 :(得分:1)

部首:

extern const char    *Bittorrent;

Main(在main函数之前/作为gloabal变量):

const char    *Bittorrent     =   "BitTorrent protocol";

这样你的标题告诉每个文件都有名为“Bittorrent”的变量,但是只有你的main.c文件中有一个部分才能真正创建它。

答案 3 :(得分:1)

通过初始化变量,您可以在包含文件的每个位置定义它。假设这些模块链接在一起,您现在有多个定义,这是一个错误。

可以使用extern标记声明标头中的变量,然后在你的.c模块中初始化它。

在你的.h文件中:

extern int i;

在你的一个.c文件中:

int i = 1;

然而,

答案 4 :(得分:1)

另请注意,您有拼写错误。

Send_fisrt_Handshake代替Send_first_Handshake

我可以想象你只是把它误输入了你的问题。但你永远不知道;在大型代码中很难找到并修复拼写错误。 :)