700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C语言不要重复包含.h头文件和.c文件

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

时间:2024-04-26 22:55:05

相关推荐

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

1.不要重复包含头文件

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

f3.h

//#ifndef AE_OK#define AE_OK 0typedef int ngx_int_t;//#endif

f2.h

#include "f3.h"

f1.h

#include "f3.h"

test.c

#include <stdio.h>#include "f1.h"#include "f2.h"int main(){ngx_int_t a1=1;printf("%d",AE_OK);printf("%d",a1);return 0;}

编译不过去:

导出预编译文件:

...以上省略# 2 "test.c" 2# 1 "f1.h" 1# 1 "f3.h" 1typedef int ngx_int_t;# 1 "f1.h" 2# 4 "test.c" 2# 1 "f2.h" 1# 1 "f3.h" 1typedef int ngx_int_t;# 1 "f2.h" 2# 5 "test.c" 2int 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" 1typedef int ngx_int_t;# 1 "f1.h" 2# 4 "test.c" 2# 1 "f2.h" 1# 5 "test.c" 2int main(){ngx_int_t a1=1;printf("%d",0);printf("%d",a1);return 0;}

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

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

在redis源码的ae.c文件:

#include <stdio.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <poll.h>#include <string.h>#include <time.h>#include <errno.h>#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#endifaeEventLoop *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 < setsize; 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 <sys/epoll.h>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文件编译的时候不需要重复引入,不然编译报错:

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

成功编译:

生成了redis文件。

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

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

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

原因分析:

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。