zoukankan      html  css  js  c++  java
  • C语言中宏定义(#define)时do{}while(0)的价值(转)

    C语言中宏定义(#define)时do{}while(0)的价值

    最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总结了一下讨论,加上自己的理解,do{...}while(0)的价值主要体现在:

    1. 增加代码的适应性

    下面的宏定义没有使用do{...}while(0)

    #define FOO(x) foo(x); bar(x);

    这样宏定义,单独调用不会出现问题,例如:

    FOO(100)

    宏扩展后变成:

    1
    foo(x);bar(x);

     这样调用FOO没有任何问题,但是FOO(x)不能放入控制语句中,例如

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

    经过宏扩展后,变成了

    if (condition)
        foo(x);bar(x);
    else 
        ...;

    这样就导致了语法错误,语法错误并不可怕,在编译阶段就能发现,更致命的是他有可能导致逻辑错误,这种错误编译器发现不了,一出这种问题,程序员就抓狂吧。例如:  

    if (condition)
        FOO(x);

    这段代码经过扩展后变成:

    if (condition)
        foo(x); bar(x);

    这样一来,无论condition是true还是false,bar(x)都会被调用。有没有被这煎熬过的兄弟啊?

    这时候do{...}while(0)的价值就体现出来了,修改一下FOO的定义

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

    这样FOO,放入控制语句中就没有问题了。

    也许有人说:把foo(x);bar(x)用大括号括起来不就行了吗?比如这样定义:

    #define FOO(x) { foo(x); bar(x); }

    再看下面代码:

    if (condition)
        FOO(x);
    else 
        ...;

    扩展后:

    if (condition)
        {foo(x);bar(x);} ; //注意最后这个分号,语法错误
    else 
        ...;

    照样语法错误;

    2.增加代码的扩展性

    我理解的扩展性,主要是宏定义中还可以引用其他宏,比如:

    #define FOO(x) do{OTHER_FOO(x)} while(0)
    这样我们不用管OTHER_FOO是但语句还是符合语句,都不会出现问题

    3.增加代码的灵活性

     灵活性主要体现在,我们可以从宏中break出来,例如下面的定义:

    复制代码
    #define FOO(x)  do{ 
        foo(x);  
        if(condition(x)) 
            break; 
        bar(x) 
        ..... 
    } while(0)
    复制代码
  • 相关阅读:
    如何使标签a处于不可用状态
    document.referrer的使用和window.opener 跟 window.parent 的区别
    纯CSS让overflow:auto页面滚动条出现时不跳动
    闭包的使用实例
    VMware workstation使用小技巧
    个人命令简记
    中国剩余定理
    UVA 10603 倒水问题
    Haybale Stacking(差分数组 + 求中位数的一些方法 + nth_element)
    POJ 1511 Invitation Cards (最短路的两种方法spfa, Dij)
  • 原文地址:https://www.cnblogs.com/yasepix/p/5084661.html
Copyright © 2011-2022 走看看