【发布时间】:2014-05-03 12:25:46
【问题描述】:
我一直在思考如何将宏写成安全、可读和直观的。正确使用它们应该通过它们的外观来理解,当使用不正确时编译器应该告诉你,而不是让你引入一个晦涩的错误。
在编写多行定义宏时,我通常会发现自己像这样构造它们来满足所需的条件:
#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) 方法是好的做法的原因是宏本身看起来有点奇怪,并且需要向以前没有看过该构造的任何人(至少有些人)进行一些解释.
编辑:
这是我喜欢的 cmets 中的链接之一的示例(谢谢!)。我认为它的可读性很强:
#define MYMACRO(a,b) \
if (xyzzy) asdf(); \
else (void)0
可以破解吗?
【问题讨论】:
-
是的,
do {} while(0)方法是最安全和推荐的! -
do {} while(0)是解决此问题的常用方法,特别是由于最后一行缺少分号使其看起来像一个函数。但是,我认为宏总是以某种方式“欺骗”用户,至少如果他们期望的是一个函数。 -
如果你想让它安全,你为什么不写一个函数呢?
-
我对宏使用全部大写的约定,以提醒用户参数可能会被多次评估,或者该行的效果可能不是用户期望的。
-
“如何编写用户友好的 c/c++ #define 宏”。简单:你不能:)
标签: c++ c c-preprocessor