C / C ++中的函数调用宏

时间:2015-06-04 18:16:57

标签: c++ c

如果在varius平台上以不同方式调用函数,比如foo(),那么使用宏是不好的做法吗?

例如:

#ifdef WIN32
#define ffoo(a) foo(0)
#else
#define ffoo(a) foo(a)
#endif

3 个答案:

答案 0 :(得分:3)

在C ++中,它被认为是不好的做法,你有很多其他的可能性,比如继承,重载等,它们并不是真的需要它。

答案 1 :(得分:2)

使用#define创建宏已知会导致未定义的行为。我建议使用模板而不是宏。

书中的简单例子" Effective C ++":

#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))

这样调用时会产生不同的行为(试一试):

CALL_WITH_MAX(++a,b); // a is incremented twice
CALL_WITH_MAX(++a,b+10); // a is incremented once

如果您使用的是C,则由于您没有模板或面向对象的解决方法,因此您受到的限制更为有限。

答案 2 :(得分:1)

是的,确实如此。宏不知道范围或它们放入的上下文,它们在实际编译短语之前运行并将事件替换为它。

让我们想象你想在其他地方使用ffoo名称,可能作为类的方法名称,甚至是另一个函数:

int MyClass::ffoo(int y) {}

这会意外地导致编译错误,因为ffoo(...)会扩展为函数调用,错误的标记位于错误的位置。

一个非常常见且烦人的例子是Windows API中定义的一个名为minmax的宏,一旦你尝试使用C ++ std::numeric_limits<T>::max()函数,你就会#39 ;找到糟糕的设计。

你更好的选择是内联函数,因为它们尊重语言语义,毕竟它们是函数。

#ifdef WIN32
inline int ffoo(int a) { return foo(0); }
#else
inline int ffoo(int a) { return foo(a); }
#endif

如果您所在的C89环境不支持inline关键字,您可以使用static,考虑到此次通话的大小,它不会受到伤害。