暂时感觉像是由于“;”的原因,关于使用习惯方面的问题!!

下面是copy的:

这样的宏见过么:

Cpp代码

  1. #define FOO(x) do {\
  2. some_code_line_1;\
  3. some_code_line_2;\
  4. } while (0)

(注意while(0)后面没有分号)

乍一看这个宏不过就是定义了个包含多个语句的local scope,用do..while(0)包围起来简直多此一举。直接这样不就好了么:

Cpp代码

  1. #define FOO(x) {\
  2. some_code_line_1;\
  3. some_code_line_2;\
  4. }




但问题是这两者不等价……

关键问题是前者定义出来的宏是一个非复合语句,而后者是一个复合语句。C/C++里有些语法结构对复合/非复合语句之间的区别是敏感的,例如说:

Cpp代码

  1. if ( someCond )
  2. FOO(x);
  3. else
  4. //...




要是FOO(x)展开后是一个复合语句,那么FOO(x)后面的分号“;”就会终结整个if语句,导致else子句孤立而出现编译错误。 
所以关键是那个while(0)后面不加分号。如果加了分号的话就没意义了。

如果用复合语句版本的宏,就要记得不写那个分号:

Cpp代码

  1. if ( someCond )
  2. FOO(x)
  3. else
  4. //...

但是这样与一般的函数调用风格不统一,所以很多人倾向于使用do..while(0)这个trick来把local scope包起来而不是直接用复合语句({..})。

印象中这类的宏还有一个变种,

Cpp代码

  1. #define FOO(x) switch(0) default: ...

还是怎样的。具体是怎么写的忘记了……以后想起来的话一定得记下来 T T

关于C语言宏定义 使用do{ xxxx }while()的更多相关文章

  1. C 语言宏定义

    C 语言宏定义1.例子如下: #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...

  2. 将C语言宏定义数值转换成字符串!

    将C语言宏定义转换成字符串! 摘自:https://blog.csdn.net/happen23/article/details/50602667 2016年01月28日 19:15:47 六个九十度 ...

  3. C语言 宏定义之可变参数

    可变参数宏定义 C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏.可变参数宏就像下面这个样子: #define dbgprint(. ...

  4. C语言宏定义时#(井号)和##(双井号)的用法1

    #在英语里面叫做 pound 在C语言的宏定义中,一个#表示字符串化:两个#代表concatenate 举例如下: #include <iostream> void quit_comman ...

  5. C语言宏定义时#(井号)和##(双井号)的用法

    C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...

  6. c语言宏定义

    一. #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时 ...

  7. C语言宏定义相关

    写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些成熟软件中常用得宏定义......1,防止一个头文件被重复包含#ifndef COMDEF_H# ...

  8. 转:C语言宏定义时#(井号)和##(双井号)的用法

    转自:http://www.cnblogs.com/welkinwalker/archive/2012/03/30/2424844.html#2678295 #在英语里面叫做 pound 在C语言的宏 ...

  9. c语言宏定义#define的理解与资料整理

    1. 利用define来定义 数值宏常量 #define 宏定义是个演技非常高超的替身演员,但也会经常耍大牌的,所以我们用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码就就都认 ...

随机推荐

  1. Python学习【第十篇】基础之杂货铺

    字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存. 百分号方式: ...

  2. swift:谈谈swift几种常见属性的区别

    一.前奏 Swift作为一门新语言,经过几年的发展,逐渐趋于完善,目前已经更新到3.0版本,它汇集许多其他语言的特点,例如JS.Paython.C++等,完全区别于OC.个人感觉它没有完全的OOP和O ...

  3. lua table integer index 特性

    table.maxn (table) Returns the largest positive numerical index of the given table, or zero if the t ...

  4. mac安装paramiko

    $ brew install openssl $ /usr/local/opt/openssl/bin/c_rehash $ export ARCHFLAGS="-arch x86_64&q ...

  5. linux rhel7 dock6.7安装

    1. 下载dock6.7 先申请license 在这个网址下载http://dock.compbio.ucsf.edu/Online_Licensing/index.htm 2. tar zxvf * ...

  6. 反编译android的apk

    将要反编译的APK后缀名改为.rar或 .zip,并解压   得到其中的classes.dex文件(它就是java文件编译再通过dx工具打包而成的),将获取到的classes.dex放到之前解压出来的 ...

  7. Docker镜像的管理和创建

    1. Docker镜像和Docker容器:      Docker镜像实际上是一系列的文件系统,通常的Linux系统一般是两层文件系统,bootfs和rootfs,bootfs就是bootloader ...

  8. visual studio 两个以上sln 引用同一个project ,生成时会改变projectguid问题

    当两个以上解决方案添加现有项,选择了同一个项目,那么在 sln 文件中,会自己带一个guid. 当打开两个解决方案,一个生成时,会影响另一个的project值,导致每次都看到了签出. 解决办法,打开共 ...

  9. splitFile2SmallFile

    1. split file into several files """ this is aa customizable version of the standard ...

  10. Core 1.0中publishOptions Include的bug

    "publishOptions": { "include": [ "wwwroot", "Views", "A ...