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 ...
随机推荐
- (三)MongoDB数据库注意
1.数据库名 数据库也通过名字来标识.数据库名可以是满足以下条件的任意UTF-8字符串. 不能是空字符串(""). 不得含有' '(空格)...$./.\和\0 (空字符). 应全 ...
- 纯小白入手 vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
vue3.0 CLI 真小白一步一步入手全教程系列:https://www.cnblogs.com/ndos/category/1295752.html 我的 github 地址 - vue3.0St ...
- url override and HttpSession implements session for form
url 重写结合HttpSession实现会话管理之 form 提交 package com.test; import javax.servlet.ServletException; import j ...
- Python+Selenium笔记(七):WebDriver和WebElement
(一) WebDriver WebDriver提供许多用来与浏览器交互的功能和设置,通过WebDriver的功能和一些方法,来实现与浏览器窗口.警告.框架和弹出窗口的交互,它也提供了自动化操作浏览器 ...
- 关于kernel-devel、kernel-header和kernel src的区别
A kernel-header package would contain 'header files' needed by some applications which would be buil ...
- APP性能测试指标和测试方法
流量 常用方法 方法一:Android系统自带统计功能(总体流量数值) Proc/uid_stat/{UID}/tcp_snd和tcp_rcv UID是每个app安装时候分配的唯一编号用于识别该app ...
- 在 Azure Resource Manager 中为虚拟机设置密钥保管库
Note Azure 具有两种不同的部署模型,用于创建和处理资源:Resource Manager 模型和经典模型.本文介绍使用 Resource Manager 部署模型.Azure 建议对大多数新 ...
- [CENTOS7] 将域群组加入到Sudoer里
文章来源:https://derflounder.wordpress.com/2012/12/14/adding-ad-domain-groups-to-etcsudoers/ Adding AD d ...
- 7zip批量压缩,并批量改.jar
批量压缩.bat--要和将要压缩的文件在同一级目录下 for /d %%X in (*) do "D:\Program Files\7-Zip\7z.exe" a "%% ...
- react的新手基础知识笔记
<!DOCTYPE html> <html> <head> <script src="../build/react.js">< ...