重复定义(multiple definition of)与重复包含

test-1.0使用#ifndef只是防止了头文件被重复包含(其实本例中只有一个头件,不会存在重复包含的问题),但是无法防止变量被重复定义。

vi test.c


include

include “test.h”

extern i;
extern void test1();
extern void test2();

int main()
{
test1();
printf(“ok\n”);
test2();
printf(“%d\n”,i);
return 0;
}

vi test.h


ifndef TEST_H

define TEST_H

char add1[] = “www.shellbox.cn\n”;
char add2[] = “www.scriptbox.cn\n”;
int i = 10;
void test1();
void test2();

endif

vi test1.c


include

include “test.h”

extern char add1[];

void test1()
{
printf(add1);
}

vi test2.c


include

include “test.h”

extern char add2[];
extern i;

void test2()
{
printf(add2);
for (; i > 0; i–)
printf(“%d-“, i);
}

Makefile


test: test.o test1.o test2.o
test1.o: test1.c
test2.o: test2.c
clean:
rm test test.o test1.o test2.o

错误:
test-1.0编译后会出现”multiple definition of”错误。

错误分析:
由于工程中的每个.c文件都是独立的解释的,即使头文件有

ifndef TEST_H

define TEST_H

….

enfif

在其他文件中只要包含了global.h就会独立的解释,然后每个.c文件生成独立的标示符。在编译器链接时,就会将工程中所有的符号整合在一起,由于文件中有重名变量,于是就出现了重复定义的错误。

解决方法
在.c文件中声明变量,然后建一个头文件(.h文件)在所有的变量声明前加上extern,注意这里不要对变量进行的初始化。然后在其他需要使用全局变量的.c文件中包含.h文件。编译器会为.c生成目标文件,然后链接时,如果该.c文件使用了全局变量,链接器就会链接到此.c文件 。

注解:c/c++就这么规定:不可以在.h里定义变量,因为就是会触发这个重复定义错误。你只能在.h里用extern bool a;这样声明变量。

全局变量的定义就应当放在C文件里。然后在H文件里,用extern做外部声明。在需要用这个变量的源文件里包含上面这个H文件。

因为#include 是把后面的文件展开 就是static了,展开后还是两份它为每个include它的文件生成一份数据,编译是对每个.cpp文件做的操作。

你这个重复定义可以通过编译, 但是在将多个.cpp编译出来的.obj文件链接成一个exe文件时就会有同一个变量在几个obj中都有定义, 这样就出错了, 链接器不知道到底该链接哪个定义的变量

ifndef GLOBAL_DEFINE

define GLOBAL_DEFINE

endif

// 这个只是用来防止Global.h被重复inlcude,在循环递归include中。只能防止你在一个源文件里,重复包含了头文件。

宏定义是局部有效的,就是在同一个编译单元中,也就是一个cpp文件。另外一个cpp文件再次判断#ifndef GLOBAL_DEFINE仍然会为TRUE。
你的情况是,有好几个源文件都各自包含了这个头文件,那么,当然,头文件里的变量就在几个源文件里都定义了
注解end

test-2.0

vi test.c


include

include “test.h”

int i = 10;
char add1[] = “www.shellbox.cn\n”;
char add2[] = “www.scriptbox.cn\n”;
extern void test1();
extern void test2();

int main()
{
test1();
printf(“ok\n”);
test2();
printf(“%d\n”,i);
return 0;
}

vi test.h


ifndef TEST_H

define TEST_H

extern i;
extern char add1[];
extern char add2[];

void test1();
void test2();

endif

vi test1.c


include

include “test.h”

void test1()
{
printf(add1);
}

vi test2.c


include

include “test.h”

void test2()
{
printf(add2);
for (; i > 0; i–)
printf(“%d-“, i);
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值