如何编写安全且用户友好的c / c ++ #define宏

时间:2014-05-03 12:25:47

标签: c++ c c-preprocessor

我一直在考虑如何编写宏以确保安全,可读和直观。正确使用它们应该通过它们的外观来理解,如果使用不当,编译器应该告诉你,而不是让你引入一个模糊的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

是否可以打破它?

1 个答案:

答案 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

这样,无论何时使宏操作无效,都不会破坏编译