Andrew Falanga
Andrew Falanga

Reputation: 2484

GCC typeof extension and math on typeof result

Today I ran across this macro in the Linux kernel (include/linux/kernel.h)

#define DIV_ROUND_CLOSEST(x, divisor)(          \
{                           \
    typeof(x) __x = x;              \
    typeof(divisor) __d = divisor;          \
    (((typeof(x))-1) > 0 ||  /* <-- why does this work */   \
     ((typeof(divisor))-1) > 0 || (__x) > 0) ?  \
        (((__x) + ((__d) / 2)) / (__d)) :   \
        (((__x) - ((__d) / 2)) / (__d));    \
}                           \
)

Now, I understand the purpose of the macro, and that it is somehow leveraging "Statement Expressions" (the link below mentions this). What I'm not understanding is how ((typeof(x))-1) > 0 amounts to anything useful. From this link in the gcc docs, I think I understand how the typeof extension is meant to be used. But knowing this doesn't seem to answer how it's used in this macro. From my own experimentation, (typeof(x)-1) doesn't seem to evaluate to anything other than -1 so isn't this always going to be less than 0 (i.e. false for the first two parts of the ternary)?


If this has already been answered, please point me to it. I did search but my attempts didn't return a result specific to this usage.

Upvotes: 3

Views: 1226

Answers (1)

caf
caf

Reputation: 239051

It's not using (typeof(x)-1) - it's using ((typeof(x))-1), which is of the form (type)value - ie, it's a cast expression.

It's casting the value -1 to the same type as the expression x, and then testing if the result is greater than zero. If x has signed integral type or floating point type the result will be false, if x has unsigned integral type the result will be true, and for most other types the behaviour will be undefined.

Upvotes: 6

Related Questions