我一直在考虑如何编写宏以确保安全,可读和直观。正确使用它们应该通过它们的外观来理解,如果使用不当,编译器应该告诉你,而不是让你引入一个模糊的bug。
在编写多行定义宏时,我通常会发现自己像这样构造它们以满足所需的标准:
#define macro(x) do{ \
... some code line ; \
... some code line ; \
}while(0)
这样你就可以......
if (a)
{
macro(a);
}
和...
if (a)
macro(a);
else
{
...
}
这样做的一个很好的功能是,如果你错误地使用它们,你将收到编译器错误。这不会编译,例如:
if (a)
macro(a)
else
b();
但是,我看到SW开发人员阅读了这种宏构造,并对它感到非常困惑。您是否可以考虑使用其他方法来编写宏,这些宏不会以某种方式欺骗用户,而是在他们执行非预期的操作时,并且在浏览新代码时仍然可以理解?
另外,你能找到do {} while(0)方法的任何问题吗?例如,您可能希望宏以某种方式行事,而不是这种情况。
我不完全相信do {} while(0)方法是一个好习惯的原因是宏本身看起来有点奇怪,并且对任何人(至少某些人)之前没有看过该构造的人进行一些解释
编辑:
以下是我喜欢的评论中的一个链接(谢谢!)的示例。我觉得这很可读:
#define MYMACRO(a,b) \
if (xyzzy) asdf(); \
else (void)0
是否可以打破它?
答案 0 :(得分:6)
当您希望宏不执行任何操作并使用预处理器切换此行为时,常用的方法是使用void(0)
操作。
#if SOMETHINGS
#define macro(x) do{ \
... some code line ; \
... some code line ; \
}while(0)
#else
#define macro(x) ((void)(0))
#endif
这样,无论何时使宏操作无效,都不会破坏编译