如果在varius平台上以不同方式调用函数,比如foo()
,那么使用宏是不好的做法吗?
例如:
#ifdef WIN32
#define ffoo(a) foo(0)
#else
#define ffoo(a) foo(a)
#endif
答案 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中定义的一个名为min
和max
的宏,一旦你尝试使用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
,考虑到此次通话的大小,它不会受到伤害。