do while(0)在宏定义中的应用

C语言宏定义中使用 do{}while(0) 的情形 先来看宏定义的一个经典例子;使用MFC;新建单文档工程,把宏定义在视类CPP文件头部; void CHongdoView::OnDraw(CDC* pDC) { CHongdoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CString str1; int x = 101, y = 202; swap(x, y); //printf("%d %d\n" 阅读详情
看linux源码时,经常发现有宏定义用
#define XYZ \
do{...} while(0)
这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的do{..}while结构呢?原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释:

假设有这样一个宏定义
#define macro(condition) \
if(condition) dosomething()

现在在程序中这样使用这个宏:
if(temp)
    macro(i);
else
    doanotherthing();

一切看起来很正常,但是仔细想想。这个宏会展开成:
if(temp)
    if(i) dosomething();
else
    doanotherthing();

这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的。

为了避免这个错误,我们使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0) 这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。

此外,这是为了含多条语句的宏的通用性。因为默认规则是宏定义最后是不能加分号的,分号是在引用的时候加上的。

在MFC的afx.h文件里面, 你会发现很多宏定义都是用了do...while(0)或do...while(false)。

为了看起来更清晰,这里用一个简单点的宏来演示:
#define SAFE_DELETE(p) do{ delete p; p = NULL } while(0)
假设这里去掉do...while(0),
#define SAFE_DELETE(p)   delete p; p = NULL;
那么以下代码:
if(NULL != p) SAFE_DELETE(p)
else   ...do sth...
就有两个问题,
1) 因为if分支后有两个语句,else分支没有对应的if,编译失败。
2) 假设没有else, SAFE_DELETE中的第二个语句无论if测试是否通过,会永远执行。
你可能发现,为了避免这两个问题,我不一定要用这个令人费解的do...while,  我直接用{}括起来就可以了
#define SAFE_DELETE(p)   { delete p; p = NULL;}
的确,这样的话上面的问题是不存在了,但是我想对于C++程序员来讲,在每个语句后面加分号是一种约定俗成的习惯,这样的话,以下代码:
if(NULL != p)  SAFE_DELETE(p);
else   ...do sth...
由于if后面的大括号后面加了一个分号,导致其else分支就无法通过编译了(原因同上),所以采用do...while(0)是做好的选择了。

如果使用名家的方法

#define SAFE_FREE(p)   do {free(p);p=NULL;}  while(0)

那么

if(NULL!=p)

        SAFE_FREE(p);

else

         do something

展开为

if(NULL!=p)

do

      { free(p);p=NULL;}

while(0);

else

        do something

好了 这样就一切太平了。

STC8H开发(十六): GPIO模拟SPI驱动Ci24R1实现低成本无线遥控 本文详细介绍了如何使用STC8H单片机通过GPIO模拟SPI驱动Ci24R1无线模块,实现低成本无线遥控方案。内容涵盖硬件设计要点、软件驱动开发技巧及实战优化经验,特别适合消费电子产品开发者参考。Ci24R1凭借其高性价比和双模协议支持,成为替代传统nRF24L01+的理想选择。 阅读详情

相关推荐

开放平台 - 互动玩法演进之路

随着直播业务和用户规模日益壮大,如何丰富直播间内容、增强直播间内用户互动效果,提升营收数据变得更加关键。

bilibili_TC的博客 1740

do...while(0) 在宏定义中的应用

 这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的do{...}while结构呢?我曾一度在心里把它叫做“怪圈”。原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释:一方面假设有这样一个宏定义#define macro(condition) /if(condition) dosomething()现在在程序中这样使用这个宏:i

anuo的专栏 879

DaVinci Configurator实战:从DBC导入到通信栈配置全解析

本文详细解析了如何使用Vector DaVinci Configurator工具,从导入行业标准DBC文件开始,高效完成AutoSAR通信栈(包括COM、PduR、CanIf等模块)的自动化与精细化配置。文章通过实战步骤,重点阐述了DBC导入、与EB MCAL协同、核心模块参数调整及诊断标定服务集成等关键环节,旨在帮助汽车电子工程师快速掌握这一核心工具,提升开发效率与准确性。

weixin_29159127的博客 593

do{}while(0)

from: http://blog.youkuaiyun.com/chenhu_doc/article/details/856468 from: http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html 一、存在的意义 宏定义中的do...while(0) 构建复用库的时候,发现许多宏定义都使用了do...while(0),

wind_rabbit的专栏 1468

树莓派计算模块摄像头连接与配置全攻略:从硬件跳线到软件驱动

在嵌入式视觉项目中,摄像头模组的连接与驱动是图像采集和视频分析的基础。其核心原理是通过CSI-2高速串行接口协议传输图像数据,并依赖I2C总线进行传感器寄存器配置。这一技术方案的价值在于为工业控制、机器人等嵌入式设备提供了稳定、高性价比的视觉感知能力。在实际应用中,开发者常面临摄像头无法识别、I2C通信失败等挑战,尤其是在使用树莓派计算模块时,其硬件接口需要通过I/O板引出,配置过程涉及设备树参数调整等关键步骤。本文聚焦于解决这些实际问题,详细拆解了从硬件连接到软件驱动的完整流程,特别是针对CM4、CM3+

weixin_29184075的博客 336

MOSFET导通电阻Rdson全解析:物理组成、公式推导与工程选型要点

在功率电子设计中,MOSFET作为核心开关器件,其导通电阻Rdson直接决定导通损耗与系统效率。从半导体物理角度看,Rdson并非单一固定值,而是由源极电阻、沟道电阻、累积层电阻、JFET区电阻、漂移区电阻及衬底电阻等多个分量串联而成,并随栅极驱动电压、结温以及击穿电压等级发生显著变化。理解Rdson的物理来源与数学表达,有助于工程师在低压大电流与高压小电流等不同场景中合理选型、优化驱动电压并准确估算热损耗。文章从沟道电阻公式出发,深入剖析耐压与导通电阻的物理矛盾、温度系数的影响规律,并给出数据手册参数的正

weixin_29163857的博客 197

深入浅出 C 语言中的 do{..}while(0):宏定义的秘密武器

深入浅出 C 语言中的 do{..}while(0):宏定义的秘密武器在 C 语言编程中,我们常常会遇到while、for、if-else这些熟悉的循环和条件语句,它们逻辑清晰,用法直观。然而,有一种构造却总是让人摸不着头脑——do{..}while(0)。乍一看,它似乎只是while循环的变种,功能完全可以被替代,那为什么 C 语言之父 Dennis Ritchie 要设计它?它究竟有什...

Francis的博客 784

Keil MDK 5.37及之后版本 安装AC5(ARMCC)编译器详细步骤

由于Keil 5.37及之后版本不再默认安装AC5(ARMCC)编译器,这就会导致由AC5编译的工程无法正常编译,往往输出窗口会提示以下信息:*** Target ‘STM32xxxx‘ uses ARM-Compiler ‘Default Compiler Version 5‘ which is not available.

s_Modesto的博客 1万+

c语言do while的好处,do{}while(0)宏定义的好处

通过do-while(0)宏定义将代码打包起来,成为一个独立的语法单元,从而不会引起上下文混淆,同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低下面就举几个上下文混淆的例子来说明do-while(0)的好处例1先看一个简单的宏#define SAFE_FREE(p) do {free(p);p=NULL;} while(...

weixin_29327977的博客 619

RT-Thread Studio 使用笔记(七)| 配合STM32CubeMX添加裸机驱动(以ADC为例)

1. 配置STM32CubeMX 2. 复制stm32xxxx_hal_msp.c文件 将 CubeMx 生成的代码 stm32f7xx_hal_msp.c 函数复制到 RT-Thread Studio 生成的工程中,并参与工程编译: 由于我们并没有使用 CubeMx 生成的工程,所以这里需要将 stm32f7xx_hal_msp.c 文件中 #include “main.h” 替换为 #i...

Mculover666的博客(嵌入式) 9627

破晓之光:GTK#框架让C# WinForm程序跨平台运行的终极指南

GTK#框架的出现,彻底打破了C# WinForm只能在Windows上运行的桎梏。

墨夶的博客 605

C/C++预处理指令和宏定义#define及 do while(0)

本文主要记录了C/C++预处理指令 #define 宏定义 do/while(0) 什么时候使用

一丁的博客 1164

windows下宝塔安装教程

windows下宝塔安装教程 目录宝塔是什么?宝塔安装流程1.下载2.配置3.登录4.安装的环境套件小结 宝塔是什么? 宝塔是管理服务器的免费的软件,宝塔上面可以进行对你的服务器批量进行管理,对于运维人员来说还是必不可少的一个软件,值得使用。 宝塔安装流程 1.下载 链接: https://download.bt.cn/win/panel/BtSoft.zip 下载后安装买最好自定义目录,方便找 2.配置 下载完成后会出现这个页面,对着页面进行配置 点击默认密码复制进来,这里注意一点就是一定要查看

你在看屏幕的同时,屏幕也在注视着你 4423

宏定义中使用do{}while(0)的好处

#define MACRO_NAME(para) do{macro content}while(0)的格式,总结了以下几个原因:1,空的宏定义避免warning:#define foo() do{}while(0)2,存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。3,如果出现在判断语句过后的宏,这样可以保证作为一个整体来是实现:#define foo(

liliangbao的专栏 2万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

do...while(0)的妙用

http://www.cppblog.com/SmartPtr/archive/2007/07/03/27443.html   By SmartPtr(http://www.cppblog.com/SmartPtr/)     在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do..

victoryckl的专栏 688

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

do{}while(0)实现宏定义

do{}while(0)实现宏定义 在定义宏尤其是定义多语句宏时,经常会看见如下定义: #define compute(a,b) do {add(a,b);sub(a,b);} while(0) 这样定义的宏有2个好处,它可以不受大括号、分号的影响,不论在什么情况下使用宏,宏都可以按照定义者的原本设计运行而不会出错;同时可以避免出现空的宏定义。 在定义多语句宏时,经常会出现分号导致运行结果出...

weixin_43814616的博客 1025

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

宏定义代码块之 do{} while(0) 的使用

在 main 函数中,我们可以像使用单个语句一样使用 MY_MACRO ,并且后续的代码不会受到宏定义中的多条语句的影响。主要的目的是为了解决宏定义在使用时可能引发的一些问题,例如宏定义中的分号和大括号的使用。}while(0),将你的代码写在里面,里面可以定义变量而不用考虑变量名会同函数之前或者之后的重复。,允许在宏定义中使用局部变量。总而言之, do{} while(0) 的作用是为了解决宏定义在使用时可能引发的一些问题,确保宏定义可以作为单个语句使用,并且在逻辑上看起来像是一个语句。

weixin_53592457的博客 2289

C++ do...while(0) do...while(false)的妙用

转载自网络,如有版权问题,请和本人联系,谢谢! do...while(0) do...while(false)的妙用    在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视。    但是,最近在读我们项目的代码时,却发现了do...while的一些十分

我相信分享也是一种能力 2706

do{}while(0)的妙用

do...while(0)的妙用 在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视。 但是,最近在读我们项目的代码时,却发现了do...while的一些十分聪明的用法,不是用来做循环,而是用作其他来提高代码的健壮性。 1. do...while

铸剑娃的专栏 3504

do...while(0)妙用

1、使宏定义更安全 2、在需要错误处理时,减少代码冗余度和goto的使用 1、假设有如下代码: #define p {A;B} ... if(COND) p;//不符合编程习惯————通常语句后加分号 else .... 当然,如果上述语句不加分号,是不会出现问题的。用do…while(0)的好处是可以将加分号贯彻到底。 #define p do{A;B;}while(0) 2、处理错误时...

jojozym的博客 328

java中的CondVal_转载:do...while(0)的妙用

MTK中有很多有关do...while(0)的应用,刚开始可能有很多人不太明白为什么使用do...while(0),似乎不加do...while(0),该部分的代码也会只执行一次,其实do...while(0)是出于优化代码考虑的.do...while(0)并不是程序员为了炫耀自己的技术而展示的奇巧淫技,而是有实实在在的功能用途的.兹转载一篇文章共同研究.在C++中,有三种类型的循环语句:for,...

weixin_36048512的博客 240

do...while(0)在宏定义中的巧妙用法

2014年08月14日 20:04:20 luoweifu 阅读数:16058 标签: C++ 宏 收起 个人分类: C++ 版权声明:本文为博主原创文章,未经博主允许不得用于任何商业用途,转载请注明出处。 https://blog.youkuaiyun.com/luoweifu/article/details/38563161 大家都知道,do…while(condition)可以表示循环,但你有没有遇...

u010029439的博客 393

do{}while(0)宏定义的好处

<br /> <br />转载自:http://blog.ednchina.com/fpga2006/34658/message.aspx<br /> #define MACRO_NAME(para) do{macro content}while(0)<br /> 的格式,总结了以下几个原因:<br />  <br /> 1,空的宏定义避免warning:<br /> #define foo() do{}while(0)<br />  <br /> 2,存在一个独立的block,可以用来进行变量定义,进行比

miyunhong的专栏 652

do...while(0) do...while(false)的妙用

do...while(0) do...while(false)的妙用     在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一 般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视。     但是,最近在读我们项目的代码时,却发现了do...while的一些十分聪明的用法,不是用来做循环,而是用作其他来提高代码

free4wuyou的专栏 657
上一篇: static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较
下一篇: linux 内存分配机制 (转)
otuhacker
博客等级 码龄18年 21粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值