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