欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

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

发布时间:2025/3/21 编程问答 48 豆豆
生活随笔 收集整理的这篇文章主要介绍了 c语言 自动包含头文件,C语言不要重复包含.h头文件和.c文件 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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

2012

1.不要重复包含头文件

--以上出自《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;

}

编译不过去:

导出预编译文件:

...以上省略

# 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文件编译的时候不需要重复引入,不然编译报错:

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还没有声明,从而陷入错误。

《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

总结

以上是生活随笔为你收集整理的c语言 自动包含头文件,C语言不要重复包含.h头文件和.c文件的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。