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

下面是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. 2.Linux如何学习

    Linux的应用: 企业应用 个人应用 平行运算:所谓的平行运算指的是将原本的工作分成多份然后交给多台主机去运算,最终再将结果收集起来的一种方式.由于通过高速网络使用到多台主机(集群),将原本需要很长 ...

  2. h5的离线缓存机制

    什么是Manifest: 其实Manifest是一个简单的 文本文件,它的扩展名是任意的,定义需要缓存的文件.资源,当第一次打开时,浏览器会自动缓存相应的资源. Manifest 的特点: 离线浏览: ...

  3. matlab直方图均衡,使用向量优化

    matlab自带有histeq函数对图像进行直方图均衡 自己写了一个,改成向量化形式,效率提高了一点,但是比自带的还是差很多,差不多9倍 function D = my_histeq(I) [m,n] ...

  4. pip install 安装python-requests

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-requests

  5. Java 高精度数字

    BigInteger // 高精度整数 BigDecimal //高精度小数  小数位数不受限制

  6. C# 连接Oracle ,免安装客户端

    在.NET平台下开发Oracle应用的小伙伴们肯定都知道一方面做Oracle开发和实施相比SqlServer要安装Oracle客户端(XCopy.自己提取相关文件也有一定复杂性),另一方面相比JAVA ...

  7. form表单编码方式设置为multipart/form-data,后台参数出现乱码情况

    一般在上传图片过程中,form中的编码方式一般采用multipart/form-data方式编码,但是后台这取参数时,可能会出现乱码情况:这里后台要采用转换编码方式: 页面: 后台:获取表单元素时,

  8. 在Eclipse 中使用tomcat8

    最新版本的Eclipse让人不支持 Tomcat 8,该方法让Eclipse能使用Tomcat8 第一步:下载最新版本Eclipse for Java EE 第二步:到WTP downloads pa ...

  9. NLog配置文件根节点

    NLog.config 配置文件信息 <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi ...

  10. 夺命雷公狗-----React---22--小案例之react经典案例todos(完成数据的遍历)

    在很多前端框架中todos都是一个小的参考例子,在react中当然也是不例外的,先来看看最终的效果先... 这个就是官方的例子,我们先来分析下他是由那及格组建组合成的... 再来分析下他是的数据最终是 ...