没有参数的预处理宏和带零个参数的预处理宏有什么区别?

37

有什么理由更喜欢

#define MY_MACRO() ..stuff..

为了

#define MY_MACRO ..stuff..

不使用宏并不是一个有效的答案...

2
由于您添加了C++标签,因此不使用宏是一个有效的答案。如果您只想讨论预处理器,请将其标记为预处理器而不是C++。 - Martin York
15
@Martin: 预处理器与STL一样是C++的一个组成部分,那么关于STL的问题应该标记为[stl]而不是[c++]吗?尽管在C++中大多数情况下不建议使用宏,但有时它们可以极大地帮助。 - James McNellis
6
事实上,如果没有宏的话,实现Boost库几乎是不可能的! - In silico
3个回答

23

仅当宏名称后跟左括号时,函数式宏才会进行替换。因此,以下所有内容都会调用函数式宏MY_MACRO()

MY_MACRO()
MY_MACRO ( )
MY_MACRO
( )

但这样做是不行的:

MY_MACRO SomethingElse

这取决于您如何使用宏以及宏的用途是否重要。理想情况下,您的宏都应具有不同的名称;如果您将全大写标识符保留给宏,则无论您使用零参数的类对象宏还是函数宏都不重要。

从美学上讲,通常(但并非总是)最好不要使用零参数的函数宏。


正如我下面所指出的,如果MY_MACRO代表的是一个依赖于环境条件(比如针对OS X和Windows不同的函数)的函数,那么在没有使用括号的情况下使用它可以通过函数指针传递该函数,这可能会有所帮助。 - Chris Lutz
那么我可以说下面这两个宏定义在功能上是等效的吗? #define MIN0( ) X < Y ? X : Y
#define MIN X < Y ? X : Y
- Andrew S
有一种情况下,希望看到类似函数的宏定义,那就是当你执行没有返回值的语句时。此时,看到 MY_MACRO; 会显得很奇怪,因为它看起来像一个常量值被写成了语句。在我看来,MY_MACRO(); 更加清晰易懂。 - Victor Zamanian

12

我更喜欢使用带括号的MY_MACRO(),因为这样更像我在调用函数。否则看起来就像我在调用一个常量:

MY_MACRO();

vs

的翻译是“对比”或“与”。
MY_MACRO;

如果这个定义被用来调用代码,而不仅仅是一个简单的常量值,那么就会出现这种情况。


9
如果MY_MACRO只是函数的一个包装器(可能在某个地方隐藏或需要根据环境进行更改),那么定义它时不加括号可以让你将该函数作为函数指针传递给其他函数,这可能有用也可能没有用。 - Chris Lutz
从另一个角度来看,这也会增加另一个需要担心的宏符号。 struct state {int errno; /* ERROR!*/ }; - yyny

1

如果您需要传递参数,则宏(x)是首选。如果您只是进行简单的“替换”,则我认为最好使用#define BLAH...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接