• do{......}while(0)的妙用


    在Linux内核和其它一些著名的C库中有许多使用do{...}while(0)的宏定义。这种宏的用途是什么?有什么好处?

    Google的Robert Love(先前从事Linux内核开发)给我们解答如下:

    do{...}while(0)在C中是唯一的构造程序,让你定义的宏总是以相同的方式工作,这样不管怎么使用宏(尤其在没有用大括号包围调用宏的语句),宏后面的分号也是相同的效果。

    其实用一句话概括就是:使用do{...}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。

    1. 避免由宏引起的警告

    内核中由于不同架构的限制,很多时候会用到空宏。在编译的时候,这些空宏会给出warning,为了避免这样的warning,我们可以使用do{...}while(0)来定义空宏:
    #define EMPTYMICRO do{}while(0)
    这种情况不太常见,因为有很多编译器,已经支持空宏。

    2.帮助定义复杂的宏以避免错误

    举例来说,假设你需要定义这样一个宏:

    #define DOSOMETHING() foo1(); foo2();

    这个宏的本意是,当调用DOSOMETHING()时,函数foo1()和foo2()都会被调用。但是如果你在调用的时候这么写:

    if(a>0)
        DOSOMETHING();

    因为宏在预处理的时候会直接被展开,你实际上写的代码是这个样子的:

    if(a>0)
        foo1();
        foo2();

    这就出现了问题,因为无论a是否大于0,foo2()都会被执行,导致程序出错。

    那么仅仅使用{}将foo1()和foo2()包起来行么?比如:

    #define DOSOMETHING() { foo1(); foo2(); }

    我们在写代码的时候都习惯在语句右面加上分号,如果在宏中使用{},代码编译展开后宏就相当于这样写了:“{...};”,展开后就是这个样子:

    if(a>0)
    {
        foo1();
        foo2();
    };

    很明显,这是一个语法错误(大括号后多了一个分号)。
    现在的编译器会自动检测自动忽略分号,不会报错,但是我们还是希望能跑在老的编译器上。

    在没有do/while(0)的情况下,在所有可能情况下,期望我们写的多语句宏总能有正确的表现几乎是不可能的。
    如果我们使用do{...}while(0)来定义宏,即:

    #define DOSOMETHING() \
            do{ \
              foo1();\
              foo2();\
            }while(0)\

    这样,宏被展开后,上面的调用语句才会保留初始的语义。

    do能确保大括号里的逻辑能被执行,而while(0)能确保该逻辑只被执行一次,就像没有循环语句一样。

    使用do{......}while(0)把复杂的实现包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。

    同时因为绝大多数的编译器能够识别do{......}while(0)这种无用的循环并进行优化,不会导致程序的性能降低。

    总结:

    在Linux和其它代码库里的,很多宏实现都使用do/while(0)来包裹他们的逻辑,这样不管在调用代码中怎么使用分号和大括号,而该宏总能确保其行为是一致的。



    参考引用链接:
    https://www.jianshu.com/p/99efda8dfec9
    https://www.cnblogs.com/lanxuezaipiao/p/3535626.html
  • 相关阅读:
    mysql5.6 sql_mode设置为宽松模式
    utf-8 编码问题
    阿里云服务器挂载云盘
    maven打包含有多个main程序的jar包及运行方式
    AndroidStudio OpenCv的配置,不用安装opencv manager
    图片标注工具LabelImg使用教程
    关于tensorboard启动问题
    IntelliJ IDEA 最新激活码(截止到2018年10月14日)
    JetBrains C++ IDE CLion配置与评测
    Win10下Clion配置opencv3
  • 原文地址:https://www.cnblogs.com/ggzhangxiaochao/p/15871771.html
Copyright © 2020-2023  润新知