Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写安全且用户友好的c/c++#定义宏_C++_C_C Preprocessor - Fatal编程技术网

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

C++ 如何编写安全且用户友好的c/c++#定义宏,c++,c,c-preprocessor,C++,C,C Preprocessor,我一直在思考如何编写安全、可读和直观的宏。正确使用它们应该通过它们的外观来理解,如果使用不正确,编译器应该告诉您,而不是让您引入一个模糊的bug 在编写多行定义宏时,我通常会这样构造它们以满足所需的条件: #define macro(x) do{ \ ... some code line ; \ ... some code line ; \

我一直在思考如何编写安全、可读和直观的宏。正确使用它们应该通过它们的外观来理解,如果使用不正确,编译器应该告诉您,而不是让您引入一个模糊的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();
然而,我看到软件开发人员阅读了这种宏构造,并对此感到相当困惑。你能想出其他方法来编写宏吗?这些宏不会欺骗用户,让用户在浏览一段新代码时仍然可以理解

另外,您能发现do{}while(0)方法有什么问题吗?例如,在这种情况下,您可能希望宏以某种方式运行,但实际情况并非如此

之所以我不完全相信do{}while(0)方法是一种好的实践方法,是因为宏本身看起来有点奇怪,需要向以前没有见过该构造的任何人(至少有些人)解释一下

编辑:

下面是我喜欢的评论(谢谢!)中一个链接的例子。我认为它很可读:

#define MYMACRO(a,b)   \
    if (xyzzy) asdf(); \
    else (void)0

有可能破坏它吗?

当您希望宏不执行任何操作,并使用预处理器切换此行为时,一种常见的方法是使用
void(0)
操作

#if SOMETHINGS
#define macro(x)    do{                      \
                        ... some code line ; \
                        ... some code line ; \
                    }while(0)
#else
#define macro(x) ((void)(0))
#endif

这样,您就不会在清空宏操作时中断编译

是的,
do{}while(0)
方法是最安全的,也是推荐的
do{}while(0)
是实现这一点的常用方法,特别是因为最后一行没有分号,使它看起来像一个函数。但是,我认为宏总是以某种方式“欺骗”用户,至少如果他们希望得到一个函数。如果你希望它是安全的,为什么不写一个函数呢?我使用宏的所有大写约定,提醒用户,参数可以被多次评估,或者这句话的效果可能不是用户期望的。“如何编写用户友好的c/c++#定义宏”。很简单:你不能:)你可能不得不修改
else
版本,因为不同的编译器会发出不同的死代码警告。为什么不在第二种情况下定义宏(x)?@FilipeGonçalves,因为如果你有类似
if(macro(x))的代码
如果(macro(x))永远不会使用原始宏定义编译,则不会在每次切换
宏的存在时编译代码
do-while
构造不是表达式,因此不能在
if
中使用。我想说,如果将原始宏用作语句,那么定义宏(x)
就足够了。虽然我没有尝试过,但我猜
if((void)(0))
也不会编译,因为您使用
void
值作为测试条件。您可以看到有关模拟
无操作的宏的说明。我以名称
macro
为例,这个
macro
不能包含在
if
子句的主体中。另一个原因是在发生赋值的地方显式中断编译,以防止排除的宏发生状态突变。