为什么有人用未使用的参数/参数定义C宏?

时间:2010-07-02 15:29:45

标签: c macros

我正在浏览一些代码,我遇到了这个宏定义

#define D(x) do { } while (0)

它在像这样的代码中使用,

D(("couldn't identify user %s", user));

我运行了代码,并且该特定行没有做任何事情。那么,为什么有人会定义这样的宏?

如果您想知道,该宏是在_pam_macros.h头文件中定义的。

2 个答案:

答案 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个月,你可能不得不拿出一些你认为已经完成的代码,并且你会憎恨过去的自我,让你搞砸了。

现在,在你的情况下,宏没有变成一个函数,只是被删除或从未填充。