Linux中的do{...} while(0)
摘抄自: <<Linux设备驱动开发详解(第二版)>>
在 Linux 内核中,经常会看到do{} while(0)这样的语句,许多人开始都会疑惑,认为do{} while(0)毫无意义,因为它只会执行一次,加不加do{} while(0)效果是完全一样的,其实 do {}
while(0)的用法主要用于宏定义中。
这里用一个简单点的宏来演示:
#define SAFE_FREE(p) do{ free(p); p = NULL;} while(0)
假设这里去掉 do...while(0),即定义 SAFE_DELETE 为:
#define SAFE_FREE(p) free(p); p = NULL;
那么以下代码
if(NULL != p)
SAFE_DELETE(p)
else
.../* do something */
会被展开为:
if(NULL != p)
free(p); p = NULL;
else
.../* do something */
展开的代码中存在两个问题。
(1)因为 if 分支后有两个语句,导致 else 分支没有对应的 if,编译失败。
(2)假设没有 else 分支,则 SAFE_FREE 中的第二个语句无论 if 测试是否通过,都会执行。
的确,将 SAFE_FREE 的定义加上{}就可以解决上述问题了,即:
#define SAFE_FREE(p) { free(p); p = NULL;}
这样,代码:
if(NULL != p)
SAFE_DELETE(p)
else
... /* do something */
会被展开为:
if(NULL != p)
{ free(p); p = NULL; }
else
... /* do something */
但是,在 C 程序中,每个语句后面加分号是一种约定俗成的习惯,那么,如下代码:
if(NULL != p)
SAFE_DELETE(p);
else
... /* do something */
将被扩展为:
if(NULL != p)
{ free(p); p = NULL; };
else
... /* do something */
这样,else 分支就又没有对应的 if 了,编译将无法通过。假设用了 do {} while(0),情况就不一样了,同样的代码会被展开为:
if(NULL != p)
do{ free(p); p = NULL;} while(0);
else
... /* do something */
不会再出现编译问题。do while(0)的使用完全是为了保证宏定义的使用者能无编译错误地使用宏,它不对其使用者做任何假设。
Linux中的do{...} while(0)的更多相关文章
- LINUX中ORACLE 11.2.0.1 升级到11.2.0.4
11.2.0.4补丁号13390677,共7个文件,分别是 其中1&2是db,3是grid,4是client,5是gateways,6是example,7是deinstall 上传安装介质并解 ...
- linux中shell变量$#,$@,$*,$?,$$,$!,$_,$0,$1,$2的含义解释
变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行的命令的结束代码(返回值) ...
- 在Linux中安装ASPNET.Core3.0运行时
# 以下示例适用于x64位runtime v3.0.0 mkdir /runtimes cd /runtimes wget https://download.visualstudio.microsof ...
- linux中shell变量$#,$@,$0,$1,$2的含义解释
linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...
- linux中shell变量$#,$@,$0,$1,$2的含义解释
linux中shell变量$#,$@,$0,$1,$2的含义解释 linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID ...
- Linux中Zabbix4.0的搭建
Zabbix简介 Zabbix是一个高度集成的企业级开源网络监控解决方案,与Cacti.nagios类似,提供分布式监控以及集中的web管理界面.zabbix具备常见商业监控软件所具备的功能,例如主机 ...
- Linux中shell变量$0,$?等含义
linux中shell变量$#,$@,$0,$1,$2的基本含义: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...
- 【转】linux中shell变量$#,$@,$0,$1,$2的含义解释
原文网址:http://www.cnblogs.com/fhefh/archive/2011/04/15/2017613.html linux中shell变量$#,$@,$0,$1,$2的含义解释: ...
- 【Shell】linux中shell变量$#,$@,$0,$1,$2的含义解释 && set 关键字使用
linux中shell变量$#,$@,$0,$1,$2的含义解释 摘抄自:ABS_GUIDE 下载地址:http://www.tldp.org/LDP/abs/abs-guide.pdf linu ...
随机推荐
- [Android] 压缩图片并保存
不难,但用的时候有时候突然会想不起来..记录一下吧 原文地址请保留http://www.cnblogs.com/rossoneri/p/3995096.html 先加权限 <uses-permi ...
- LeetCode题解之Sort List
1.题目描述 2.问题分析 使用sort算法 3.代码 ListNode* sortList(ListNode* head) { if( head == NULL || head->next = ...
- C#多线程的用法9-Semaphore
Semaphore:可理解为允许线程执行信号的池子,池子中放入多少个信号就允许多少线程同时执行. private static void MultiThreadSynergicWithSemaphor ...
- 如何用SQL脚本在SQL Server Replication中创建合并复制,以及怎么创建分区合并复制
假设我们要创建合并复制的发布端数据库是EFDemo其中有四张表,订阅端数据库是EFDemoSubscription,如下图所示: 首先创建发布端快照代理Sql agent job:"EFDe ...
- leveldb源码阅读
http://blog.csdn.net/sparkliang/article/details/8567602 http://brg-liuwei.github.io/tech/2014/10/15/ ...
- 【C语言】 使用Beep() 函数 演奏歌曲
#include <windows.h> int main(){ ){ Beep(, ); Beep(, ); Beep(, ); Beep(, ); Beep(, ); Beep(, ) ...
- Oracle 导出用户下的所有索引创建语句
SELECT dbms_lob.substr(dbms_metadata.get_ddl('INDEX', INDEX_NAME))||';' from dba_indexes where owne ...
- win10 损坏 bios?
自从前几个月升级为win10后,主板莫名奇妙的就出问题了,遇到3块不同型号2块技嘉b75,1块微信ph67 技嘉b75-ds3v 技嘉b75m-d3v 微星ph67s-c43 ms-7673 1.0 ...
- 3.5星|《订阅》:Youtube对用户喜好的发现与应对
订阅:数字时代的商业变现路径 主要内容我总结是Youtube对用户喜好的发现与应对.可以认为很多时候作者说的是Youtubu官方的态度与想法.穿插了许多Youtube上的成功创作者的故事. Youtu ...
- DAU、UV、独立IP、PV的区别和联系
基本概念 DAU(Daily Active User)日活跃用户数量.常用于反映网站.互联网应用或网络游戏的运营情况.DAU通常统计一日(统计日)之内,登录或使用了某个产品的用户数(去除重复登录的用户 ...