宏定义中,为什么使用:do{}while(0)这种模式是最安全的

news/2025/10/7 14:23:54/文章来源:https://www.cnblogs.com/long005/p/19128469

如果你是一名C程序员,你肯定很熟悉宏,它们非常强大,如果正确使用可以让你的工作事半功倍。然而,如果你在定义宏时很随意没有认真检查,那么它们可能使你发狂,浪费N多时间。在很多的C程序中,你可能会看到许多看起来不是那么直接的较特殊的宏定义。下面就是一个例子:

1
2
#define __set_task_state(tsk, state_value)      \
     do  { (tsk)->state = (state_value); }  while  (0)

在Linux内核和其它一些著名的C库中有许多使用do{...}while(0)的宏定义。这种宏的用途是什么?有什么好处?

Google的Robert Love(先前从事Linux内核开发)给我们解答如下:

do{...}while(0)在C中是唯一的构造程序,让你定义的宏总是以相同的方式工作,这样不管怎么使用宏(尤其在没有用大括号包围调用宏的语句),宏后面的分号也是相同的效果。

这句话听起来可能有些拗口,其实用一句话概括就是:使用do{...}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。

例如:

1
#define foo(x) bar(x); baz(x)

然后你可能这样调用:

1
foo(wolf);

这将被宏扩展为:

1
bar(wolf); baz(wolf);

这的确是我们期望的正确输出。下面看看如果我们这样调用:

1
2
if  (!feral)
     foo(wolf);

那么扩展后可能就不是你所期望的结果。上面语句将扩展为:

1
2
3
if  (!feral)
     bar(wolf);
baz(wolf);

显而易见,这是错误的,也是大家经常易犯的错误之一。

 

几乎在所有的情况下,期望写多语句宏来达到正确的结果是不可能的。你不能让宏像函数一样行为——在没有do/while(0)的情况下。

如果我们使用do{...}while(0)来重新定义宏,即:

1
#define foo(x) do { bar(x); baz(x); } while (0)

现在,该语句功能上等价于前者,do能确保大括号里的逻辑能被执行,而while(0)能确保该逻辑只被执行一次,即与没有循环时一样。

对于上面的if语句,将会被扩展为:

1
2
if  (!feral)
     do  { bar(wolf); baz(wolf); }  while  (0);

从语义上讲,它与下面的语句是等价的:

1
2
3
4
if  (!feral) {
     bar(wolf);
     baz(wolf);
}

这里你可能感到迷惑不解了,为什么不用大括号直接把宏包围起来呢?为什么非得使用do/while(0)逻辑呢?

例如,我们用大括号来定义宏如下:

1
#define foo(x)  { bar(x); baz(x); }

这对于上面举的if语句的确能被正确扩展,但是如果我们有下面的语句调用呢:

1
2
3
4
if  (!feral)
     foo(wolf);
else
     bin(wolf);

宏扩展后将变成:

1
2
3
4
5
6
if  (!feral) {
     bar(wolf);
     baz(wolf);
};
else
     bin(wolf);

大家可以看出,这就有语法错误了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930505.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20251007J赛合订本

A-鲁的智力(gio) B-鲁的女孩(girl)

XML 元素:基础、应用与优化 - 教程

XML 元素:基础、应用与优化 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco…

Educational Codeforces Round 183 (Rated for Div. 2) A~D

A - Candies for Nephews 模拟。 看 \(3\) 的余数。点击查看代码 #include <bits/stdc++.h>using namespace std;using i64 = long long;void solve() {int n;std::cin >> n;std::cout << (3 - n % …

asp.net网站开发实例教程临沂网站建设 百度优化

BP神经网络指传统的人工神经网络&#xff0c;相比于卷积神经网络(CNN)来说要简单些。 人工神经网络具有复杂模式和进行联想、推理记忆的功能, 它是解决某些传统方法所无法解决的问题的有力工具。目前, 它日益受到重视, 同时其他学科的发展, 为其提供了更大的机会。1986 年, Rom…

长春网站建设硕成传媒app制作开发小程序制作开发

​  域名解析是互联网用户接收他们正在寻找的域的地址的过程。更准确地说&#xff0c;域名解析是人们在浏览器中输入时使用的域名与网站IP地址之间的转换过程。您需要站点的 IP 地址才能知道它所在的位置并加载它。但&#xff0c;在这个过程中&#xff0c;可能会出现多种因素…

网站傻瓜式建设品牌维护

文章目录 1. Socket简介2. ServerSocket3. Socket4. 服务器端代码5. 客户端代码 1. Socket简介 Socket&#xff08;Java套接字&#xff09;是Java编程语言提供的一组类和接口&#xff0c;用于实现网络通信。它基于Socket编程接口&#xff0c;提供了一种简单而强大的方式来实现…

外贸网站怎么做效果好平面设计公司怎么找客户

1.1 概述 Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。习惯优于配置 1.2 为什么使用Spring Boot J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大。 1.3 Spring Bo…

深入解析:SpringBatch+Mysql+hanlp简版智能搜索

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Cisco vManage漏洞分析:未授权RCE与权限提升完整攻击链

本文详细分析了Cisco vManage中四个关键漏洞的组合利用链,包括SSRF+任意文件写入、未授权文件读取、命令注入和SUID权限提升,最终实现未授权root权限远程代码执行,影响企业SD-WAN基础设施安全。SD-PWN — 第3部分 —…

ps做游戏下载网站seo人员培训

本文由简码编程原创&#xff0c;保留所有版权&#xff0c;转载请注明出处。 本python人工智能爬虫系列教程基于Python3.0版本, 将python结合windows桌面开发工具aardio一起做可视化的开发, 用python做逻辑处理,用aardio做窗口界面, 不用再看着黑黑的python命令行窗口, 有window…

爱建站吧软文广告推广

对python这个高级语言感兴趣的小伙伴&#xff0c;下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧&#xff01;访问FTP&#xff0c;无非两件事情&#xff1a;upload和download&#xff0c;最近在项目中需要从ftp下载大量文件&#xff0c;然后我就试着去实验自己的ftp操作类&…

铁总建设函网站怎么做招投标网站

看了很多教程&#xff0c;花了1天半的时间装上了&#xff0c;记录下。 前置条件&#xff1a;我安装了VS2015&#xff0c;用来编译工程。 参考资料 官方&#xff1a;http://www.vtk.org/Wiki/VTK/Building 安装&#xff1a;http://blog.csdn.net/Chinamming/article/details/1…

硅芯片创新如何成为云计算成功的关键

本文深入探讨了某中心通过自研芯片技术推动云计算发展的历程,包括Nitro系统、Graviton处理器及机器学习专用芯片的创新,揭示了硅芯片在提升性能、降低功耗方面的核心技术突破。硅芯片创新如何成为云计算成功的关键 某…

东萍象棋 DhtmlXQ UBB 转 中国象棋云库查询 FEN

<html><meta charset="utf-8"> <title>ubb2fen</title> <style> button { font-size:18pt; width:5em } #ta { outline:none } </style> <body> <p><bu…

【开源工具】基于PyQt5工作时长计算器工具开发全解析 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

十六、【前端强化篇】完善 TestCase 编辑器:支持 API 结构化定义与断言安装

十六、【前端强化篇】完善 TestCase 编辑器:支持 API 结构化定义与断言安装2025-10-07 14:04 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x…

斑马ZT210碳带及纸张安装教程

1、碳带安装方法说明图:2、纸张安装说明图:3、综合图:4、实物图:

石家庄网站搭建定制vi设计获奖作品

一.概述 1.1 以太网指的是由Xerox公司创建并由Xerox、Intel和DEC公司联合开发的基带总线局域网规范&#xff0c;是当今现有局域网采用的最通用的通信协议标准。以太网络使用CSMA/CD技术。 1.2 以太网在局域网各种技术中占统治性地位。 造价低;是应用最广泛的局域网技术。比令…

DHCP及DNS

dhcp enable //开启dncp ip pool xxx //创建一个叫xxx的地址池 network xxx.xxx mask yyy.yyy//设置地址池的相关参数 gateway-list zzz.zzz//设置地址池的网关 dns-list ddd.ddd//设置地址池的DNS huawei路由器还…