0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

"最常见"却又"最不常用"的三个预编译

Q4MP_gh_c472c21 来源:最后一个bug 作者:bug菌 2020-11-16 15:55 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1

#error 与#warning

谈到预编译大家常用的有#if、#else、#ifdef、#ifndef、#endif等等条件编译选项。

然而在我们阅读一些大型的代码或者库的时候,一般都会看到有#error和#warning,可能有些小伙伴一扫而过并没有了解清楚这些预编译指令到底该怎么用,写了很久的代码估计也重来没有敲过他们。

#error / #warning

形式 :#error / #warningmessage

作用 :生成一个编译错误事件并停止编译/发出警告信息

注意 :message可以不需要双引号。

参考demo:

#include #include //#defineconfigUART_N5 #ifndefconfigUART_N #errorconfigUART_Nmustdefine //#error"configUARTmustdefine" //#warning"configUARTmustdefine" #endif #ifconfigUART_N>4 #errorconfigUART_Nmustnotbelessthan4 //#error"configUART_Nmustnotbelessthan4" //#warning"configUART_Nmustnotbelessthan4" #endif /*************************************** *Fuction:进行预编译测试 *Author:(最后一个bug) **************************************/ intmain(intargc,char*argv[]){ printf("公众号;最后一个bug "); return0; }

输出结果:

编译失败,无法生成可执行文件

上面是放开宏,且使用warning的情况,无其他错误的情况下可以生成可执行文件。

解释一下:

通过上面的测试代码可以了解到,通过配合条件预编译#if等,#error和#warning能够在编译过程中分别以错误和告警的形式提醒开发人员注意相关代码设计问题,从而保证代码正确性。

这样对于发布一些庞大的库代码时,为了让开发人员正确的使用库,这些提示会帮助他更好的移植代码。

那么经常有很多小伙伴编译出来的代码有一大堆warning,总是觉得warning关系不大,然而warning也是分不同类型的,对于一些未使用的变量倒关系不大,其他情况还是要认真对待,最好是做到"0 Error,0 warning".

2

#undef

#undef标识符用于把前面的宏定义名取消,别看这宏用得不多,作用可大着呢,下面我简单举几个例子:

1

局部宏定义

一旦定义了宏,那么该文件中往下所有的代码都可以使用该宏,即使是函数内部,这样导致宏比较混乱,如下面代码:

参考demo:

#include #include #defineconfigRatio10 /*************************************** *Fuction:获得传感器电压值 *Author:(最后一个bug) **************************************/ intGetSensorVolt(void) { #defineconfigRatio1 intret=0; ret=configRatio*1024;//比例因子*AD值 returnret; //#undefconfigRatio } /*************************************** *Fuction:获得传感器电压值 *Author:(最后一个bug) **************************************/ intGetSensorCurr(void) { #defineconfigRatio2 intret=0; ret=configRatio*1024;//比例因子*AD值 returnret; //#undefconfigRatio } /*************************************** *Fuction:进行预编译测试 *Author:(最后一个bug) **************************************/ intmain(intargc,char*argv[]){ printf("configRatio=%d ",configRatio);//报宏未定义 printf("GetSensorVolt=%d ",GetSensorVolt()); printf("GetSensorCurr=%d ",GetSensorCurr()); printf("公众号;最后一个bug "); return0; }

输出结果:

解释一下:

假如我们没有注意到函数内部的同名宏定义,当然告警也没管,那么在main函数中使用同名宏定义就可能不是我们期待的最上面的宏定义,造成程序bug。

所以我们可以使用#undef来限制每个宏的作用域,如果每个函数内部都使用了#undef,那么main函数中再使用会报宏没有定义,这样便可以找到问题,当然也可以通过警告了解到。

2

选择接口

通过宏来切换不同的接口供程序使用:

参考demo:

#include #include #include #defineDEV_SPI #include"Drive.h" #undefDEV_SPI /*************************************** *Fuction:进行预编译测试 *Author:(最后一个bug) **************************************/ intmain(intargc,char*argv[]){ char*strbug="thelastbug"; SendData(strbug); ProcessData(strbug); printf("公众号;最后一个bug "); return0; }

#include #ifdefDEV_UART #defineSendData(s)printf("UARTSend:%s ",s) #defineProcessData(s)printf("UARTProcess:%s ",s) #endif #ifdefDEV_CAN #defineSendData(s)printf("CANSend:%s ",s) #defineProcessData(s)printf("CANProcess:%s ",s) #endif #ifdefDEV_SPI #defineSendData(s)printf("SpiSend:%s ",s) #defineProcessData(s)printf("SpiProcess:%s ",s) #endif

输出结果:

3

自定义接口

当多个人维护一套代码的时候,有些同事喜欢调用库函数接口,而有些同事喜欢调用自定义接口,为了方便统一使用自定义接口或者库接口,我们会进行如下操作:

参考demo:

#include #include #include #include"Drive.h" //#undefprintf /*************************************** *Fuction:进行预编译测试 *Author:(最后一个bug) **************************************/ intmain(intargc,char*argv[]){ char*strbug="thelastbug"; printf("公众号;最后一个bug "); return0; }

#ifndef__DRIVE_H__ #define__DRIVE_H__ #defineprintfprintf("pleaseuseKprintf! "); externvoidKprintf(char*str); #endif

输出结果:

这样下面的代码你就只能够使用Kprintf来进行输出打印,而当我们放开注释掉的宏,这样就又可以使用printf了,还是比较方便的。

责任编辑:lq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73148
  • 编译
    +关注

    关注

    0

    文章

    688

    浏览量

    34944

原文标题:"最常见"却又"最不常用"的三个预编译

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    #define预编译的指令

    #define预编译指令 顾名思义,这个指令的含义是“定义”,大家可以把该指令视为一种文本的替换。详细在下面代码展示 [list=1] [*]//使用该指令定义了一数 [*]#define
    发表于 12-05 07:29

    #include预编译的指令

    众所周知#include“xxx.h”的作用是用来包含头文件的,作用是能够调用头文件中的各类枚举/结构体/函数定义等。那么一C文件是如何通过#include“xxx.h”文件就能编译到那些定义呢
    发表于 12-04 07:43

    未来工业AI发展的三个必然阶段

    与优化 能力的深层革命。 未来十年,工业AI的发展将经历三个清晰的阶段:  智能辅助 → 智能决策 → 自主优化 。这次进化,构成了工业从“人控机器”到“机器共智”的核心路径。 一、第一阶段:智能辅助(AI for Assistance) 时间窗口:
    的头像 发表于 10-27 15:47 235次阅读
    未来工业AI发展的<b class='flag-5'>三个</b>必然阶段

    请问K230D的三个相机能同步采样吗?

    如题 K230D的三个相机能同步采样吗?
    发表于 08-04 06:32

    NVMe IP开发速成: 三个月不是梦

    作为NVMe IP开发者,在构建IP时总是需要不断修改,然后编译上板测试,每一次编译,少则20分钟,多则两三个小时,对IP的热情总是在满怀期待的希望等待中磨灭,NVMe IP开发工具作为一
    的头像 发表于 04-14 19:52 821次阅读
    NVMe IP开发速成: <b class='flag-5'>三个</b>月不是梦

    半导体制造过程中的三个主要阶段

    前段工艺(Front-End)、中段工艺(Middle-End)和后段工艺(Back-End)是半导体制造过程中的三个主要阶段,它们在制造过程中扮演着不同的角色。
    的头像 发表于 03-28 09:47 5673次阅读
    半导体制造过程中的<b class='flag-5'>三个</b>主要阶段

    如何检测极管的三个

    可以用万用表来初步确定极管的好坏及类型 (NPN 型还是 PNP 型 ),并辨别出e(发射极)、b(基极)、c(集电极)三个电极。
    发表于 03-08 16:40

    如何区分场效应管mos管三个引脚

    场效应管mos管三个引脚怎么区分
    发表于 03-07 09:20 0次下载

    如何在三个三个或更多现场可编程门阵列* (FPGA) 设备上同时运行OpenVINO™?

    无法同时使用三个FPGA卡在同一模型上进行推理
    发表于 03-06 07:15

    Linux系统中最重要的三个命令

    Linux剑客是Linux系统中最重要的三个命令,它们以其强大的功能和广泛的应用场景而闻名。这三个工具的组合使用几乎可以完美应对Shell中的数据分析场景,因此被统称为Linux
    的头像 发表于 03-03 10:37 797次阅读

    使用DDS生成三个信号并在Vivado中实现低通滤波器

    本文使用 DDS 生成三个信号,并在 Vivado 中实现低通滤波器。低通滤波器将滤除相关信号。
    的头像 发表于 03-01 14:31 2444次阅读
    使用DDS生成<b class='flag-5'>三个</b>信号并在Vivado中实现低通滤波器

    dlpc3470的datasheet上,这三个脚位分别对应的pin number是什么?

    dlpc3470的datasheet上,这三个脚位分别对应的pin number是什么?
    发表于 02-21 07:19

    DLPA3000 VRST、VOFFSET、VBIAS三个电压可以外接LED灯指示吗?

    我想分别使用三个LED灯串联1~20K电阻来表示三个电压已经有输出了,但是看到datasheet上有下面的描述,所以是否不能直接驱动?
    发表于 02-21 06:00

    ADS828的GND引脚有三个,这三个引脚的接地是哪个接数字地,哪个接模拟地?

    在贵公司的这款AD转换芯片ADS828的GND引脚有三个(1、16、26)想咨询一下这三个引脚的接地是哪个接数字地,哪个接模拟地,还是不用考虑这方面;还有就是在输出偏置电压的时候,在为2.5V的时候,是用CM输出端好,还是用REFT和REFB电阻分压好?
    发表于 02-14 08:27

    Triton编译器的常见问题解决方案

    Triton编译器作为一款专注于深度学习的高性能GPU编程工具,在使用过程中可能会遇到一些常见问题。以下是一些常见问题的解决方案: 一、安装与依赖问题 检查Python版本 Triton编译
    的头像 发表于 12-24 18:04 6397次阅读