当前位置:首页 > 公众号精选 > typedef
[导读]有个粉丝关于条件编译的问题,程序一直编译报错。我整理了关键的部分,下面代码是头文件中的定义。

粉丝问答

有个粉丝关于条件编译的问题,程序一直编译报错。我整理了关键的部分,下面代码是头文件中的定义。

#ifdef EXTERN  #undef EXTERN #define EXTERN #else #define EXTERN extern #endif EXTERN int a;

报错的内容就是error: unknown type name 'EXTERN,报错的地方是EXTERN int a;

分析

乍一看条件编译好像并没有什么不妥,但编译器确实已经报错了,那就只能说确实没有定义?。

首先,用户的意图是想用宏EXTERN代替关键字extern。

针对此模块,要保证EXTERN就是extern,所以需要判断外部是否已经定义了EXTERN。如果已经定义了,则需要取消宏定义后再重新定义。

那这里又有同学问了,如果外部已经定义了EXTERN,为什么还要取消宏定义再重新定义呢,直接用不可以吗?

严格来说是不行的,假设外部有个地方定义了

#define EXTERN const 

那么此时EXTERN就不再是extern了,意义完全变了。这时候又有同学说了,怎么可能会有人把EXTERN定义成const呢,我只能说,我也希望不会出现这种情况吧...

如果外部没有定义EXTERN会进入else分支,则在本模块直接定义。

看起来都是这么合情合理。

查看预编译文件

上面已经分析了一次,逻辑上好像没问题(指出问题了我还这么继续写下文)。既然分析没有问题,那我们直接去看预处理文件吧,简单写个Demo,头文件不变。

gcc生成预编译命令为gcc -E .\main.c -o main.i参数E代表预编译处理,o代表输出,后面跟一个文件名。代表将源文件预编译处理将处理的结果输出到main.i文件中。

内部定义EXTERN

假设我们在源文件包含头文件之前已经定义了EXTERN,如下:

#include #define EXTERN extern #include"main.h" 

然后对源文件预编译处理并截取关键信息:

# 10 ".\\main.h" int a;
# 4 ".\\main.c" 2 

未定义EXTERN

源文件部分代码,此时没有定义EXTERN。

#include #include"main.h" 

同样对源文件预编译处理并截取关键信息:

# 10 ".\\main.h" extern int a;
# 4 ".\\main.c" 2 

对比

当外部定义了EXTERN时,头文件预编译的结果没有对变量a做extern声明。外部定义了EXTERN时,头文件预编译的结果对变量a做了extern声明。

结果

宏的本质是代码替换,上述对比表明,当外部定义了EXTERN时,在处理EXTERN int a;前EXTERN变成了一个空宏。

那我们再回头看看头文件中的条件编译,如果外部定义了EXTERN则取消宏定义,并重新定义EXTERN,但是在重新定义宏的时候,这里仅仅是定义了EXTERN。并没有指明EXTERN是extern。所以编译总是提示unknown type name 'EXTERN

问题2-宏的处理顺序

问题已经找出来了,但是粉丝现在又有了新的疑问,同一个宏在多个文件是如何处理的?

其实上面的两种测试代码已经能够表明了,因为预编译也是按照先后顺序依次处理的,所以宏的处理过程也是按照先后顺序。这也是我为什么在包含main头文件之前定义EXTERN,而不是在包含头文件之后定义EXTERN

延伸问题-宏判断

发现有些同学对于一些宏的判断有些分不清楚,不清楚应该在何种场合使用。在此仍然以EXTERN为例吧。

第一种

#define EXTERN 

依稀记得当时刚毕业出来工作,当我第一次看到代码有这种定义的时候,也是挺懵逼的。甚至怀疑是不是写错了?因为我当时认为后面少了数字。为什么是少数字呢,因为在我的印象中宏都是下面这种使用方法。

#define VALUE (100) 

第一种方式宏定义仅仅代表定义了这个标识符,而不用关心它具体是什么。

常用的就是在调试模式下定义DEBUG,发布程序的时候将DEBUG关闭。主要是用来打印一些信息,方便程序员调试用的,如下:

#ifdef DEBUG //打印信息 #endif 

第二种

#if EXTERN 

注意这种使用方法,是一个判断语句,跟我们编程用if判断逻辑相同,也就是EXTERN不为0才能成立。

这种用法通常都是在定义宏时直接定义成1,例如:

#define EXTERN (1) 

第三种

#ifdef EXTERN 

这种方式和第二种有区别,这种判断只关注有没有定义,但凡你定义了,不管是什么牛马蛇神,条件都是成立的。

最后

关于宏相关的知识点,之前写过一篇文章。有兴趣的可以看看。

C语言中宏定义的盲区

这篇文章主要也是宏相关的,主要是实际编程中的问题。条件编译报错,可以去查看预处理文件,反向分析。如果你对C理解得比较深,可能一眼就能看出问题所在了。

每个人都是从小白过来的,需要时间慢慢沉淀,慢慢也就好了,加油~

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭