How do we use nested if else with #define preprocessor

Viewed 493
#define len(a) if (a == 8)   1       \
               else if (a == 3) 0    \
               else -1

this code is just an example how do we use nested if else. I don't want to use ternary operator as in that case i can't use else if statement.

5 Answers

Don't abuse the preprocessor. Use a real function:

constexpr auto len(int const a) {
    if (a == 8) return 1;
    if (a == 3) return 0;
    return -1;
}
inline __attribute__((always_inline)) int len(const int a)
{
    switch(a)
    {
        case 8: return 1;
        case 3: return 0;
    }
    return -1;
}

If you can use GNU extensions and insist on a macro with if-else branching, you can use compound statement expression:

#define len(a) ({                 \
    int _res = -1;                \
    if ((a) == 8) _res = 1;       \
    else if ((a) == 3) _res = 0;  \
    (_res); })

This works both in C and C++. Unfortunately, such compound statements cannot be used in constant expressions.

Re: "I don't want to use ternary operator as in that case i can't use else if statement" -- well, yes, you can't use else if in a ternary operator. But you can use another ternary operator:

int x = a == 8 ? 1
    : a == 3 ? 0
    : -1;

There is no issue in writing nested or not if statements in a macro, or at least no more issues than usual when you try to wrap statements in macros. But note that I used statement, there is no such thing as an if expression in either C or C++ excepted the ternary operator you don't want to use.

So if you want nested ifs statements in a macro, you can do something like

#define stmt(c1, c2) \
   if (c1) \
      do_1(); \
   else if (c2) \
      do_2(); \
   else \
      do_3()

(note that the way to escape end of lines is with \ and not with /). If you want an expression, you'll have either to use the ternary operator or a function as showed in other answers. Well, even if you need statements, I'd suggest to use a function instead of a macro.

Related