1

When exploring a source package, I discovered that some if statements were defined by preprocessor directives and then used in the code like the example below:

#ifdef _WIN32
    #define OSisWindows() true
    #define OSisLinux() false
#elif defined(__linux__)
    #define OSisLinux() true
    #define OSisWindows() false
#endif

if ( OSisWindows() )
{
// do something
}

if ( OSisLinux() )
{
// do something else
}

Is there a difference between using this and simple defines like _WIN32 or __linux__ ?

6
  • 2
    Eww, they're just trying to imitate functions, but bool OSisWindows() {return true;} works just as well. Commented Jun 12, 2014 at 14:02
  • Real functions will actually work better: if I'm not mistaken, putting whitespace before the argument list parentheses (which should be allowed) will result in the macro tokens failing to match. Commented Jun 12, 2014 at 14:03
  • @chris: If those particular functions are used a lot, then it might affect the performance as the function call itself will take some resources. Of course, you could just make it inline and that wouldn't be an issue either. Commented Jun 12, 2014 at 14:04
  • 2
    @wolfPack88, Not a chance. The optimizer will jump on that, with or without an explicit inline. Commented Jun 12, 2014 at 14:05
  • 1
    @FrédéricHamidi: You can invoke a function-like macro with spaces between the name and the open parenthesis. You just can't define one like that. To prevent macro expansion on a "call" you need to surround the name with parentheses: (OSisWindows)() Commented Jun 13, 2014 at 7:07

4 Answers 4

4

Well, you can't use a macro directly in your code like:

if ( _WIN32 ) {
    ...
}

on linux for example because it isn't defined so they are simply mapping the macro to a boolean expression.

In in end, it's really a style decision though... they could have certainly done:

#ifdef _WIN32
    ...
#endif
Sign up to request clarification or add additional context in comments.

5 Comments

You could if it was #define _WIN32 1 or something. I'm not sure about any guarantees on that, though.
yeah, just edited my answer on that... on Windows it's defined to 1 so it works but on other platforms it wouldn't be defined...
The not defined case can be handled like if (_WIN32+0)
if _WIN32 is not defined that won't compile
You could put in your code: #ifndef _WIN32 #define _WIN32 0 #endif. But at this point, I'm just being difficult.
3

Assuming the macros are defined, the advantage of using an if..else statement over an #if .. #else directive is all code paths are compiled in the first case so if there are compile errors the compiler is able to see them in all the code paths. Of course this isn't always possible as some code paths may be platform dependent code.

Comments

1

In addition to what's already been written it's another layer of abstraction. If for example the syntax for _WIN32 changes or you want to explicitly compile for windows without relying on the flag, you'd have to change your complete code in case you would have used _WIN32 directly. In this case you could just change the preprocessor directives.

Comments

0

Is there a difference between using this and simple defines like _WIN32 or linux ?

No, this is simple macro abuse.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.