C++ 何时以及为什么使用#定义宏(x)而不是函数?

C++ 何时以及为什么使用#定义宏(x)而不是函数?,c++,c,macros,C++,C,Macros,看到这些,我不禁想知道为什么会采用这种方法(玩具示例): 将永远被优先于功能: void foo(unsigned x){ bar[x] = 0; } 在上面链接的问题之前,我在PolarSSL库中只见过一次,我认为这是某种优化,并尽量不去想太多 我假设使用预处理器宏将“call”替换为“(not-)函数体”,无论它在哪里存在;然而,void函数可能会也可能不会被编译器优化,因此可能会导致一个或两个小而简单的操作出现大量分支 还有其他好处吗 何时首选宏方法,何时信任编译器更好 还有其他好处吗

看到这些,我不禁想知道为什么会采用这种方法(玩具示例):

将永远被优先于功能:

void foo(unsigned x){ bar[x] = 0; }
在上面链接的问题之前,我在PolarSSL库中只见过一次,我认为这是某种优化,并尽量不去想太多

我假设使用预处理器宏将“call”替换为“(not-)函数体”,无论它在哪里存在;然而,
void
函数可能会也可能不会被编译器优化,因此可能会导致一个或两个小而简单的操作出现大量分支

还有其他好处吗

何时首选宏方法,何时信任编译器更好

还有其他好处吗

使用宏的环境好处很少。仅举一个例子,您可以使用
\uuuu LINE\uuu
\uuu FILE\uuuu
查看调用此宏进行调试的位置

#define foo(x) bar[x] = 0; PrintFunction("...", __FILE__,__LINE__)
宏永远不会提供更强的类型检查功能

何时首选宏方法,何时信任编译器更好


因此,只有当您没有任何选择来使用函数时,才应该首选宏,因为大多数时候您可能信任编译器优化器

首先,我希望您的宏实际上是:

#define foo(x) do { bar[x] = 0; } while (0)
当然

支持宏的一个原因是,您认为编译器的优化程序不够好。你可能错了。但是如果您确实仔细查看了输出,并且知道自己在做什么,那么您可能是对的,这就是为什么它经常在Linux内核中使用

另一个原因是宏是无类型的,因此您可以:

#define foo(x,t) do { t[x] = 0; } while (0)

适用于任何类型的
t
。缺少类型检查通常是一个缺点,但在定义要处理任何类型的内容时,它可能很有用。

定义宏只是为了加快代码的速度是没有用的。一个好的编译器可以内联 函数调用。但是,当需要将宏的结果用作常量时,宏可能很有用

#define ENCODED(a,b,c,d) (((((((a)<<8)+b)<<8)+c)<<8)+d)

switch (a) {
   case ENCODED('f','o','o','0'):   ...
   case ENCODED('b', 'a', 'r', '1'): ...
}
当你想做一些其他的“魔术”时,。例如:

#define assert(x) {if ((x) == 0) {printf("%s:%d: Assertion %s failed\n", __FILE__, __LINE__, #x); exit(-1); }}
当您想要定义一个使用多种类型的“通用”函数时。仅作说明:

#define DELETE_LAST_ITEM(x) {while (x->next->next != NULL) x=x->next ; x->next = NULL}

和其他一些我现在不记得的情况。

在C和C++中都标记了一个部分风格的问题,每个都可能不同。这不是首选。当编译器还没有很好的优化器时,那些宏是Ab/As使用的。或者在C++和C99之前。@ HANSPASANTA:好的,我将继续引导自己:然后,不是所有可以用宏完成的事情都可以用函数来完成。了解宏可以做什么,但在函数可以完成相同任务时使用函数。它们不需要完全避免。“其他”原因在C++中由于模板而过时了。我从来没有使用过一个,我只是编造了,所以我很不幸地在分号上窒息。当然,但是这被标记为
C
C++
@5gon12eder,我也问过C,因为我对这样的差异/双方都感兴趣。是的,但这也是一个问题,这就是为什么我留下评论的原因。C++中宏的合理使用可能是一个可怕的问题。也许我应该把它表述成:“在C++中,其他用法由于模板而变得过时了。”常数结果是在C++中使用像C.宏这样的函数的一个正当理由,这是不必要的,并且被认为是一件坏事。任何需要编译时常量的地方都可以使用
constepr
。模板可以帮助它处理任意类型。
#define assert(x) {if ((x) == 0) {printf("%s:%d: Assertion %s failed\n", __FILE__, __LINE__, #x); exit(-1); }}
#define DELETE_LAST_ITEM(x) {while (x->next->next != NULL) x=x->next ; x->next = NULL}