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

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)

有可能打破它吗?

Nik*_*iou 6

当您希望宏不执行任何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)

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

  • 为什么在第二种情况下不直接使用“#define macro(x)”呢? (2认同)