c语言 自动包含头文件,C语言不要重复包含.h头文件和.c文件

http://blog.csdn.net/unix21/article/details/8450235

2012

1.不要重复包含头文件

71718394_1

71718394_2

71718394_3

--以上出自《C语言程序设计:现代方法(第2版)》

f3.h

//#ifndef AE_OK

#define AE_OK 0

typedef int        ngx_int_t;

//#endif

f2.h

#include "f3.h"

f1.h

#include "f3.h"

test.c

#include 

#include "f1.h"

#include "f2.h"

int main(){

ngx_int_t a1=1;

printf("%d",AE_OK);

printf("%d",a1);

return 0;

}

编译不过去:

71718394_5

导出预编译文件:

...以上省略

# 2 "test.c" 2

# 1 "f1.h" 1

# 1 "f3.h" 1

typedef int ngx_int_t;

# 1 "f1.h" 2

# 4 "test.c" 2

# 1 "f2.h" 1

# 1 "f3.h" 1

typedef int ngx_int_t;

# 1 "f2.h" 2

# 5 "test.c" 2

int main(){

ngx_int_t a1=1;

printf("%d",0);

printf("%d",a1);

return 0;

}

如果我们在f3.h中增加#ifndef就不会出问题了,直接导出预编译文件:

# 2 "test.c" 2

# 1 "f1.h" 1

# 1 "f3.h" 1

typedef int ngx_int_t;

# 1 "f1.h" 2

# 4 "test.c" 2

# 1 "f2.h" 1

# 5 "test.c" 2

int main(){

ngx_int_t a1=1;

printf("%d",0);

printf("%d",a1);

return 0;

}

2..c文件编译注意不要重复引入

这个是我从redis源码中抽取其事件库的编译

在redis源码的ae.c文件:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include "ae.h"

#include "zmalloc.h"

#include "config.h"

/* Include the best multiplexing layer supported by this system.

* The following should be ordered by performances, descending. */

#ifdef HAVE_EVPORT

#include "ae_evport.c"

#else

#ifdef HAVE_EPOLL

#include "ae_epoll.c"

#else

#ifdef HAVE_KQUEUE

#include "ae_kqueue.c"

#else

#include "ae_select.c"

#endif

#endif

#endif

aeEventLoop *aeCreateEventLoop(int setsize) {

aeEventLoop *eventLoop;

int i;

if ((eventLoop = zmalloc(sizeof(*eventLoop))) == NULL) goto err;

eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize);

eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize);

if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err;

eventLoop->setsize = setsize;

eventLoop->lastTime = time(NULL);

eventLoop->timeEventHead = NULL;

eventLoop->timeEventNextId = 0;

eventLoop->stop = 0;

eventLoop->maxfd = -1;

eventLoop->beforesleep = NULL;

if (aeApiCreate(eventLoop) == -1) goto err;

/* Events with mask == AE_NONE are not set. So let's initialize the

* vector with it. */

for (i = 0; i 

eventLoop->events[i].mask = AE_NONE;

return eventLoop;

err:

if (eventLoop) {

zfree(eventLoop->events);

zfree(eventLoop->fired);

zfree(eventLoop);

}

return NULL;

}

HAVE_EPOLL是前面定义的:

/* Test for polling API */

#ifdef __linux__

#define HAVE_EPOLL 1

#endif

在ae_epoll.c中的aeApiCreate函数

#include 

typedef struct aeApiState {

int epfd;

struct epoll_event *events;

} aeApiState;

static int aeApiCreate(aeEventLoop *eventLoop) {

aeApiState *state = zmalloc(sizeof(aeApiState));

if (!state) return -1;

state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);

if (!state->events) {

zfree(state);

return -1;

}

state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */

if (state->epfd == -1) {

zfree(state->events);

zfree(state);

return -1;

}

eventLoop->apidata = state;

return 0;

}

我想抽取出redis的事件库

一开始不知道include的.c文件编译的时候不需要重复引入,不然编译报错:

71718394_6

ae_epoll.c不用被引入,因为在ae.c已经引入了。

成功编译:

71718394_7

生成了redis文件。

2..h文件编译注意不要重复引入

报错anet.h:47: 错误:expected declaration specifiers or ‘...’ before ‘size_t’

71718394_8

原因是anet.h头文件重复引用,去掉anet.h,重新编译就可以了:

71718394_9

原因分析:

b.h中#include "../../a.h" 而a.h中的函数声明中用到了b.h中的结构体或者typedef,那么就会出现在包含a.h的时候b.h中的结构体或者typedef还没有声明,从而陷入错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值