当前位置: 首页 > news >正文

C/C++ 宏中 `do { ... } while (0)` 的“零次循环”技巧

1. 问题现象

C/C++ 宏只是简单的文本替换,若宏体包含多条语句,替换后极易出现以下两类错误:

  1. else 悬空

    #define FOO(x)  stmt1; stmt2;
    if (cond)FOO(x);   // 只有 stmt1 受 if 控制
    elsebar();
    
  2. 花括号与分号不匹配

    #define FOO(x) { stmt1; stmt2; }
    if (cond)FOO(x);   // 展开后多了一个分号,编译错误
    elsebar();
    

2. 解决方案:do { ... } while (0)

把宏体包装在 单次执行的 do-while 循环 中:

#define FOO(x) \do { stmt1; stmt2; } while (0)
  • 语义:循环体只执行一次,与 if/elseforwhile 等结构无缝衔接。
  • 语法do { ... } while (0); 末尾自带分号,用户正常写 FOO(x); 即可通过编译。

3. 正确展开示例

if (cond)FOO(x);
elsebar();

展开后:

if (cond)do { stmt1; stmt2; } while (0);
elsebar();
  • 结构完整,无 else 悬空。
  • 分号恰好被 while (0); 吸收,无多余符号。

4. 为什么不能仅用大括号

#define FOO(x) { stmt1; stmt2; }
  • 替换后:
    if (cond){ stmt1; stmt2; };   // 多余的分号导致语法错误
    elsebar();
    
  • 大括号本身不带分号,无法消化用户写下的分号。

5. 使用要点

  1. 宏体含多条语句、内部变量定义或需要“单语句”语义时,务必使用 do { ... } while (0)
  2. 对于只含一条表达式的宏,可省略此技巧,但保持一致性亦可保留。
  3. 现代 C++ 推荐用 inline 函数或模板替代宏;若必须用宏,则遵循此范式。

6. 结论

do { ... } while (0) 是一个 零成本、零副作用 的惯用法,确保宏在任何上下文中表现如一条普通语句。

http://www.dtcms.com/a/316754.html

相关文章:

  • Windows 远程管理 (WinRM)问题详解包括c#与python例子
  • vue - - - - 18n高级使用(插入变量)
  • Pycharm 2025.2 免登陆试用
  • Centos-Stream 10 安装教程(2025版图文教程)
  • [激光原理与应用-152]:光学器件 - 光栅,一种由周期性排列的等宽等间距结构组成的光学元件,通过衍射和干涉实现光的分光、调制或测量功能的光学元件
  • 详细讲述优雅草蜻蜓I即时通讯私有化中xmpp服务中的tigase的角色与作用深度分析-卓伊凡|bigniu
  • 【Istio系列--Istio基础理论和部署】
  • leetcode 104.二叉树的最大深度
  • 数据结构3-双向链表、循环链表
  • 14.Home-新鲜好物和人气推荐实现
  • 大模型|极简说清“数据并行”
  • 06-队列
  • Crawl4AI:开源的AI友好型网页爬虫与数据抓取工具
  • 电子秤利用Websocket做为Client向MES系统推送数据
  • 软件测试——接口自动化
  • STM32内部读写FLASH
  • 90、【OS】【Nuttx】【启动】栈溢出保护:配置项解析
  • Swift 实战:用队列巧解 LeetCode 346 数据流中的移动平均数
  • 服务器端口连通性的测试工具和方法
  • XXL-JOB调度中心、执行器、Job之间的关系
  • MQTT:消息详解
  • 备忘录记事本 任务清单 html
  • 基于铁头山羊STM32的平衡车电机转速开环闭环matlab仿真
  • 线性规划最优解
  • 饿了么招java开发咯
  • tarjan找SCC,缩点建DAG,找唯一源头节点
  • 强光干扰下误报率↓82%!陌讯多模态融合算法在火焰识别的落地优化
  • 不可变集合
  • nflsoi 7.31 题解
  • 信息化项目验收,项目成功的最后确认