Is it possible to use a if statement inside #define?

前端 未结 8 1712
名媛妹妹
名媛妹妹 2021-02-02 13:34

I\'m trying to make a macro with the following formula: (a^2/(a+b))*b, and I want to make sure that the there will be no dividing by zero.

#define          


        
8条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-02-02 13:51

    As far as I know, what you're trying to do (use if statement and then return a value from a macro) isn't possible in ISO C... but it is somewhat possible with statement expressions (GNU extension).

    Since #defines are essentially just fancy text find-and-replace, you have to be really careful about how they're expanded. I've found that this works on gcc and clang:

    #define SUM_A(x, y)                                     \
    ({                                                      \
        float answer;                                       \
        if ((x) == 0 || (y) == 0) {                         \
            answer = 0;                                     \
        } else {                                            \
            answer = ((float)((x)*(x)) / ((x)+(y))) * (y);  \
        }                                                   \
        answer;                                             \
    })
    // Typecasting to float necessary, since int/int == int in C
    

    Brief explanation of the things in this macro:

    • The \ at the end of each line is to signal line continuation (i.e. to tell the compiler "this macro continues on the next line")
    • The ({ is a statement expression (GNU extension; not part of standard C).
    • Though not strictly necessary, it's safer to wrap up each use of the parameter/s in parentheses to avoid operator-precedence gotchas. For example, if x was 2+1, then (x)*(x) would expand to (2+1)*(2+1), which is 9 (what we wanted), but x*x would expand to 2+1*2+1, which is 5 (not what we wanted)
    • In statement expressions, the last line functions like the return value (hence the answer; at the end)

    This should give you the result you're looking for, and there's no reason it can't be extended to include multiple else ifs as well (though as other answers have pointed out, it's probably better to use the ternary operator if you can).

提交回复
热议问题