像这样使用宏是合法的吗?

时间:2013-11-17 22:33:29

标签: c++ c macros

我有一个跨平台项目,我发现宏可能是克服某些平台不一致的最简单方法,但是因为我不是计算机科学背景,所以我不确定我们是否可以这样使用宏:

#ifndef _WIN32
  #define someWindowsFunction(x, y) someLinuxFunction(y, x, &x)
#endif

3 个答案:

答案 0 :(得分:4)

是的,这是合法的,但它是否有效取决于someWindowsFunction()的调用方式(x必须是左值)的详细信息以及所涉及的函数的行为,当然。

有很多细节需要用宏来正确完成,因为它们是简单的文本替换。你应该习惯做的一件事就是把宏观参数放在一边:

#define someWindowsFunction(x, y) someLinuxFunction((y), (x), &(x))
偶尔有些时候你不想要parens,但它们并不常见,你应该这样做,除非你知道有理由不这样做。

答案 1 :(得分:2)

虽然这不是非法的,但如果您只为其他操作系统提供功能存根,则可能更容易维护,例如:

#ifndef _WIN32
  int someWindowsFunction(char x, int y)
  {
    return someLinuxFunction(y, x, &x);
  }
#endif

答案 2 :(得分:2)

这与Windows.h标题已经非常相似。

获取或返回字符串值的每个Win32函数都定义如下:

#if _UNICODE
  #define FunctionName FunctionNameW
#else
  #define FunctionName FunctionNameA
#endif

因此,当您致电CreateWindow时,它实际上是CreateWindowACreateWindowW的宏。 Win32定义了这两个函数,然后这个宏决定调用哪个函数。

它也非常普遍,因为API的用户现在正在调用宏而不是函数。根据您的IDE,这可能会破坏自动完成/智能感知,并且它会使用大量宏来污染全局命名空间(对于一些非常常见的名称与许多其他库定义的许多其他名称冲突)的API)。

一个表现得更好的解决方案就是使用预处理器来控制哪些函数暴露给API,可能是这样的:

T someFunction(X x, Y y) {
#ifdef _WIN32
    someWindowsFunction(x, y);
#else
    someLinuxFunction(x, y, &x);
#endif
}

您可以对此做出很多可能的变化,但如果可以避免,请尽量避免使用宏来污染API。