C多行宏:do/while(0)与范围块

C多行宏:do/while(0)与范围块,c,macros,multiline,C,Macros,Multiline,可能的重复项: 我见过一些包装在do/while(0)循环中的多行C宏,如: #define FOO \ do { \ do_stuff_here \ do_more_stuff \ } while (0) #定义FOO\ 做{\ 你在这里做事吗\ 做更多的事情\ }而(0) 与使用基本块相比,以这种方式编写代码有哪些好处(如果有的话): #define FOO \ { \ do_stuff_here \ do_more_stuff \ }

可能的重复项:


我见过一些包装在do/while(0)循环中的多行C宏,如:

#define FOO \ do { \ do_stuff_here \ do_more_stuff \ } while (0) #定义FOO\ 做{\ 你在这里做事吗\ 做更多的事情\ }而(0) 与使用基本块相比,以这种方式编写代码有哪些好处(如果有的话):

#define FOO \ { \ do_stuff_here \ do_more_stuff \ } #定义FOO\ { \ 你在这里做事吗\ 做更多的事情\ }
Andrey Tarasevich提供了以下解释:

  • [对格式进行了细微更改。方括号中添加了括号注释
    []
    ]

    使用“do/while”版本的整个想法是制作一个可以 展开为常规语句,而不是复合语句。这是 这样做是为了使函数样式宏的使用与 在所有上下文中使用普通函数

    考虑以下代码草图:

    if (<condition>)
      foo(a);
    else
      bar(a);
    
    现在,如果宏是按照第二种方法定义的 (只需
    {
    }
    )代码将不再编译,因为'true' 如果现在由复合语句表示,
    的分支。当你
    放一个
    在这个复合语句之后,您完成了整个
    if
    语句,从而孤立
    else
    分支(因此产生编译错误)

    纠正此问题的一种方法是记住不要放置
    之后
    宏“调用”:

    现在这个代码:

    if (<condition>)
      CALL_FUNCS(a);
    else
      bar(a);
    
    if()
    调用函数(a);
    其他的
    巴(a);
    
    将编译没有任何问题

    然而,请注意我的定义之间的微小但重要的差异 调用函数和消息中的第一个版本。我没有把它放进去
    }之后,而(0)
    。放置一个
    位于该定义的末尾
    会立即挫败使用“do/while”和make的全部意义
    该宏相当于复合语句版本

    我不知道你在原著中引用的代码的作者为什么 将此信息放入
    之后,而(0)
    。在这种形式下,两种变体都是 相等的使用“do/while”版本背后的整个想法是 包括这最后的
    编码到宏中(出于我解释的原因
    上文)


    重复:事实上还有另一种方法可以让事情变得正确。({…})可以执行与执行{}while(0)相同的操作。Ref:@wuxb:the
    ({…})
    构造是一个GCC扩展,不受ISO标准C的支持。最初的帖子是我在
    comp.lang.C
    中发表的
    bytes.com
    显然“挪用”了
    comp.lang.c
    的内容,而没有提及源代码。
    if (<condition>)
      CALL_FUNCS(a)
    else
      bar(a);
    
    #define CALL_FUNCS(x) \
    do { \
      func1(x); \
      func2(x); \
      func3(x); \
    } while (0)
    
    if (<condition>)
      CALL_FUNCS(a);
    else
      bar(a);