C语言不要重复包含.h头文件和.c文件
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 <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还没有声明,从而陷入错误。
相关文章:
论推荐系统与精细化运营
作者丨gongyouliu来源 | 大数据与人工智能(ID: ai-big-data)随着大数据与人工智能(AI)技术的发展与成熟,国家政策层面对大数据与人工智能技术、创新、创业层面的支持,企业越来越意识到数据和AI技术的价值,并逐步认可数…

服务器产品选型与性价比图解
转载于:https://blog.51cto.com/lijichao/229471

解决jsp引用其他项目时出现的 cannot be resolved to a type错误
JSP页面引用其他项目的时候,在jsp页面上写如下代码: <%List<CandleEntity> candleEntities;CandleOperate candleOperate new CandleOperate(DataBaseEntity.getInstance()); %>虽然也添加了引用 <%page import"com.sjzh.xtrader.l…

ATT格式汇编语言
1.编译与链接 方法一:使用as #as -o test.o test.s #ld -o test test.o 方法二:使用gcc #gcc -o test test.s gnu连接器查找_start标签以确定程序的开始,但gcc查找main标签,所以使用gcc要把 _start改为main 2.调试 #as -gsta…

取得Repeater内部控件命令名与命令参数
前台: <table border"0"cellpadding"0"cellspacing"1"class"meet_tbl"><tr class"meet_title bold"><td>会议名称</td><td>制定日期</td><td>删除</td></tr…
Python在计算内存时值得注意的几个问题
作者 | 豌豆花下猫来源 | python猫(ID:python_cat)我之前的一篇文章,带大家揭晓了 Python 在给内置对象分配内存时的 5 个奇怪而有趣的小秘密。文中使用了sys.getsizeof()来计算内存,但是用这个方法计算时,可能会出现意…

HDU 1816, POJ 2723 Get Luffy Out(2-sat)
HDU 1816, POJ 2723 Get Luffy Out 题目链接 题意:N串钥匙。每串2把,仅仅能选一把。然后有n个大门,每一个门有两个锁,开了一个就能通过,问选一些钥匙,最多能通过多少个门 思路:二分通…
AI战“疫“之路:揭秘高精准无感测温系统的全栈AI 技术
在这个全民抗疫的特殊时期,今年的春节返潮来得比往年迟了许多。如今不少企业结束了远程办公,开始陆续复工,一时间,无论是重点防控的机场、火车站,还是学校、企业、社区等密集型场所,都安排了密集的防疫驻扎…

关于text段、data段和bss段
根据APUE,程序分为下面的段:.text, data (initialized), bss, stack, heap。 data/bss/text: text段在内存中被映射为只读,但.data和.bss是可写的。 bss是英文Block Started by Symbol的简称,通常是指用来存放程序中未初始化的全局…

091023 T GIX4 项目中的 智能部署 和 智能客户端
先说一下ClickOnce的使用方法:先给一个要发布的工程设置安全和签名。然后发布到iis中。当用户访问该iis目录下的.application文件时,就会自动安装整个应用程序。 再说一下我们目前的应用程序。相对还是比较复杂的,分为框架部分和特定应用程序部分。其中的…

STL学习系列九:Map和multimap容器
1.map/multimap的简介 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对。它提供基于key的快速检索能力。map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。map的具体…
人工智能改变未来教育的5大方式!
作者 | Zohaib翻译 | 天道酬勤,编辑 | Carol出品 | AI科技大本营(ID:rgznai100)科技正在改变着我们的生活、工作和娱乐方式,教育领域也不例外。 人工智能将像大多数其他领域一样全面改变教育领域,这取决于当…

程序在内存中运行的奥秘
简介当丰富多彩的应用程序在计算机上运行,为你每天的工作和生活带来便利时,你是否知道它们是如何在计算机中工作呢?本文用形象的图表与生动的解释,揭示了程序在计算机中运行的奥秘。 内存管理是操作系统的核心功能,无论…

微软虚拟化解决方案课件
微软虚拟化解决方案课件转载于:https://blog.51cto.com/yangzhiguo/231577

【Python 第8课】while
2019独角兽企业重金招聘Python工程师标准>>> 先介绍一个新东西:注释。python里,以“#”开头的文字都不会被认为是可执行的代码。 print “hello world”和 print "hello world" #输出一行字是同样的效果。但后者可以帮助开发者更…
2019年度CSDN博客之星TOP10榜单揭晓,你上榜了吗?
培根说,『读书造成充实的人,会议造成未能觉悟的人,写作造成正确的人』。在短信短视频快速迭代的快时代,更深度的思考、更正确的实践,更成体系的写作与分享,尤显可贵。这里,每一篇博文都是开发者…

objdump查看目标文件构成
objdump objdump是用查看目标文件或者可执行的目标文件的构成的GCC工具 反汇编 #objdump -d cpuid2 对于其中的反汇编代码 左边是机器指令的字节,右边是反汇编结果。显然,所有的符号都被替换成地址了, 注意没有加$的数表示内存地址&#…

jQuery--AJAX传递xml
程序代码$.ajax({ url:Accept.jsp, type:post, //数据发送方式 dataType: xml, //注意这里是xml哦 ,不是html ( html比较简单,所以我拿xml做下例子,解释下 )data:text$("#name").val()&datenewDate(), //要传递的数据 timeout: 2000, …

ActionDescriptor 的认识
ActionDescriptor的作用是对Action方法的元数据的描述,通过ActionDescriptor我们可以获取到action方法的相关的名称,所属控制器,方法的参数列表,应用到方法上的特性以及一些筛选器;ActionDescriptor是由ControllerDescriptor类中的FindAction方法进行创建; ActionDescriptor类也…

readelf和ldd分析elf文件
1. elf 文件格式 linux系统中,gcc编译器编译出的object文件、可执行文件都属于elf文件。 elf文件由三个部分组成:elf header、program headers|section headers、sections|program segments。 如果是executable文件,则section部分是不需要的…
号称3个月发布最强量子计算机,卖口罩的霍尼韦尔凭什么?
作者 | Just出品 | AI科技大本营新冠疫情的发生,霍尼韦尔这家口罩品牌引入众人眼帘。但实际上,口罩业务只是这家企业的一小块副业,它能做的业务十分多元。3月4日,霍尼韦尔宣布在量子计算领域取得突破,将提升量子计算机…

一位老工程师前辈的忠告
诸位,咱当工程师也是十余年了,不算有出息,环顾四周,也没有看见几个有出息的!回顾工程师生涯,感慨万千,愿意讲几句掏心窝子的话,也算给咱们师弟师妹们提个醒,希望他们比咱…

一站式学习Wireshark
https://community.emc.com/message/818739#818739 转载于:https://blog.51cto.com/jackprivate/1725190

objdump与readelf
objdump和readelf都可以用来查看二进制文件的一些内部信息. 区别在于objdump 借助BFD而更加通用一些, 可以应付不同文件格式, readelf则并不借助BFD, 而是直接读取ELF格式文件的信息, 按readelf手册页上所说, 得到的信息也略细致一些. 几个功能对比. 1. 反汇编代码 查看源代…

接口学习笔记(2009.11.24)
了解接口,主要是为了一道经典面试题:接口与抽象类的区别,对接口的理解却很少,现在学习一下。 接口只包含方法、属性、事件或索引器的签名。成员的实现是在实现接口的类或结构中完成的。 Interfacenamespace study1124{ interfa…
“一网打尽”Deepfake等换脸图像,微软提出升级版鉴别技术Face X-Ray
作者 | Just出品 | AI科技大本营(ID:rgznai100)Deepfake换脸图像的泛滥给人类社会带来了巨大的挑战。虽然研究者们为检测换脸图片提出了多种AI鉴别算法,但随着换脸算法的不断改造升级,鉴别算法很难跟上换脸算法的变化。微软亚洲研…

双边滤波算法的简易实现bilateralFilter
没怎么看过双边滤波的具体思路,动手写一写,看看能不能突破一下。 最后,感觉算法还是要分开 水平 与 垂直 方向进行分别处理,才能把速度提上去。 没耐性写下去了,发上来,给大伙做个参考好了。 先上几张效果图…
赔偿谷歌1.8亿美元!前Uber自动驾驶主管被告到破产
整理 | Just出品 | AI科技大本营(ID:rgznai100)两年前的Google自动驾驶部门与Uber自动驾驶技术纠纷案以和解结束后再起波澜。据路透社等外媒报道,Uber自动驾驶部门前主管安东尼莱万多夫斯基(Anthony Levandowski)周三申…

.data和.text段合并
a.c #include <stdio.h> extern int share;int main(void) { int a100;swap(&a,&share);} b.c int share1;void swap(int *a,int *b){*a^*b^*a^*b;} 编译 #gcc -c a.c b.c 链接 #ld a.o b.o -e main -o ab 查看 #objdump -h 文件 VMA即虚拟地址 size即…

用QQ提问的技巧,用了之后可以提高效率,呵呵。
有些Tx喜欢用QQ向好友提些问题,但是却没有掌握提问的技巧,自己没有及时得到答案也浪费了对方的时间。这里抛砖引玉,说一下我的看法和体会。大家一起讨论。我们讨论问题,不讨论人。 一、 把QQ当成了电话(不适合的做法&a…