c中特定“do while”宏的优点?

时间:2012-02-08 20:10:21

标签: c

我遇到的宏定义如下:

#define CALL_FUNCS(x)
do {
  func1(x);
  func2(x);
  func3(x);
} while (0);

现在,当然这会有效,但这比下面的版本更好吗?

#define CALL_FUNCS(x)
{
  func1(x);
  func2(x);
  func3(x);
}

我认为这与宏观优化无关。有什么想法吗?

4 个答案:

答案 0 :(得分:4)

宏实际上不应该有最终结果;如果出现问题,这是为了在宏周围获得正常/更多预期和有用的语法错误。

答案 1 :(得分:4)

如果您在do ... while (0)语句中未使用if-else表单,则会收到错误消息:

if (bla) CALL_FUNCS();
else statement;

将被预处理为:

if (bla)
{
  func1(x);
  func2(x);
  func3(x);
};
else statement;

else语句前的分号无效。

注意(正如@arsenm所指出的那样)你不应该将最后的;放在宏定义中的do ... while (0)之后,你必须在行之后使用\定义:

#define CALL_FUNCS(x)  \
do {                   \
  func1(x);            \
  func2(x);            \
  func3(x);            \
} while (0)

答案 2 :(得分:3)

首先,它不应该有尾随;。它应该是:

#define CALL_FUNCS(x)    do { func1(x); func2(x); func3(x); } while (0)

无论如何,原因如下。考虑

if(b)
     CALL_FUNCS(x);
else
     something_else(x);

这将扩展为:

if(b)
     { func1(x); func2(x); func3(x); };
else
     something_else(x);

现在我们仍然有一个跟踪;,并会收到以下错误消息:

error: ‘else’ without a previous ‘if’

注意,如果您将;保留在宏中,那么您将两个尾随;

宏扩展应该“看起来”像最终需要分号的东西。您不会输入CALL_FUNCS(x),而是打电话给CALL_FUNCS(x);。您可以依靠do.. while(0)来填充分号,但{ }不会这样做。

答案 3 :(得分:0)

这用于强制用户在宏调用后添加;