我遇到的宏定义如下:
#define CALL_FUNCS(x)
do {
func1(x);
func2(x);
func3(x);
} while (0);
现在,当然这会有效,但这比下面的版本更好吗?
#define CALL_FUNCS(x)
{
func1(x);
func2(x);
func3(x);
}
我认为这与宏观优化无关。有什么想法吗?
答案 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)
这用于强制用户在宏调用后添加;
。