Grigorii Alekseev
Grigorii Alekseev

Reputation: 177

C: Best way to hide if-statement in macro

What is the best practice of hiding if-statement in #define?

  1. You can use if in define:
#define MY_MACRO(isTrue) if(isTrue) do()

My intuition says that this is bad approach. Could you give an example, why it's so or why not? For example, anyone who use this can add else after macro.

  1. You can use ternary operator:
#define MY_MACRO(isTrue) (isTrue) ? do() : do_not()
//OR
#define MY_MACRO(isTrue) (isTrue) ? do() : (void)0

Here I understand, why it's not good. For example, anyone can call your function do() with simple true || MY_MACRO(?)

  1. My current solution for this issue is do-while-false
#define MY_MACRO(isTrue) do { if(isTrue) do(); } while (false)

Is this actually the best approach? What bad can happen with this macro?

Upvotes: 0

Views: 237

Answers (1)

Artyer
Artyer

Reputation: 40826

For 1, it can't be used like this:

if (foo) MY_MACRO(bar);
else something_else();

Because that would be expanded like this:

if (foo) {
    if (isTrue) {
        do();
    } else {
        something_else();
    }
}

The else will (unexpectedly) be the else for the if inside the macro.

The bad thing about your current approach is it can't be used where a statement is needed (e.g. f((MY_MACRO(a), b), c) in a comma expression won't work), but since you use it for the side effects of do(), it wouldn't be used where a statement is required.

Since it seems quite short, you can make it act like a statement, just add another pair of brackets to fix your problem with 2:

#define MY_MACRO(isTrue) ((isTrue) ? do() : (void)0)

You should also want to consider a static conditional_do(bool isTrue) { if (isTrue) { do(); } } instead of a macro.

Upvotes: 1

Related Questions