我正在浏览一些代码,我遇到了这个宏定义
#define D(x) do { } while (0)
它在像这样的代码中使用,
D(("couldn't identify user %s", user));
我运行了代码,并且该特定行没有做任何事情。那么,为什么有人会定义这样的宏?
如果您想知道,该宏是在_pam_macros.h头文件中定义的。
答案 0 :(得分:8)
最有可能D
用于调试,并且在其他地方有一个#ifdef
,如果启用调试,它会使它更有用,比如输出消息或将其记录到文件中。 do/while
循环是为了使其在结尾处需要分号,因此用户可以将其称为D(...);
,而不仅仅是D(...)
(请参阅this post)
答案 1 :(得分:0)
这样做是为了忘记添加一个;在宏的末尾,它会导致编译错误,就像它是一个函数一样。
如果你做了这个(承认没用的)宏:
#define DBG(x,y) printf ("Debug output %d\n", x); printf (" %d\n", x+y);
你可以像这样调用宏:
void someFun ()
{
DBG(10,0)
DBG(11,40)
}
它编译得非常好。
do {...} while(0)强制你包括;最后,如果宏稍后变成一个功能 - 这经常发生。进行此更改后,您可能会突然出现数千个语法错误。我定义它的方式是:
#define DBG(x,y) \
do \
{ \
printf ("Debug output %d\n", x); \
printf (" %d\n", x+y); \
} while (0)
现在你必须包括一个;在宏的最后。请记住,宏在预处理器阶段逐字地替换代码。
现在 - 还要考虑如果使用两个宏执行此操作会发生什么:
if (x==y)
DBG(x,y);
如果您使用了显示的第一个宏,它将始终打印x和y的总和,无论if是什么评估。
你可能在想,这会解决它:
#define DBG(x,y) {printf ("Debug output %d\n", x); printf (" %d\n", x+y);}
它会的,但你又回到能够忘记';'试。
清洁代码不一定是好代码,但是像垃圾一样编写的优秀代码会让你认为代码很糟糕。养成良好的习惯,因为在未来5个月,你可能不得不拿出一些你认为已经完成的代码,并且你会憎恨过去的自我,让你搞砸了。
现在,在你的情况下,宏没有变成一个函数,只是被删除或从未填充。