简体   繁体   中英

Is that legal to use macro like this?

I have a cross-platform project, I found macro could be the easiest way to overcome some platform-inconsistences, however since I am not a computer-science background, so I am not sure if we can use macro this way:

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

Yes it's legal, but whether or not it'll work depends on the details of how someWindowsFunction() is called ( x would have to be an lvalue) and the behavior of the functions involved, of course.

There are a lot of details that need to be done correctly with macros since they're simple text substitution. One thing you should get in the habit of doing is always putting parens around the macro parameters:

#define someWindowsFunction(x, y) someLinuxFunction((y), (x), &(x))

There are occasional times when you don't want parens, but they're rather uncommon and you should just do it unless you know that there's a reason not to.

While this is not illegal, it probably would be easier to maintain if you just provide function stub for other OS, like:

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

That is very similar to what the Windows.h header does already.

Every Win32 function which takes or returns a string value is defined like this:

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

So when you call CreateWindow , it is actually a macro for either CreateWindowA or CreateWindowW . Win32 defines both functions, and this macro then decides which one is called.

It is also pretty much universally hated because users of the API are now calling macros, rather than functions. Depending on your IDE, this may mess with autocompletion/intellisense, and it pollutes the global namespace with a large number of macros (for some very common names which clash with many other names defined by many other libraries and APIs).

A more well-behaved solution would be to just use the preprocessor to control which functions are exposed to the API, perhaps something like this:

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

You can make a lot of possible variations on this, but try to avoid polluting the API with macros if you can avoid it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM