if (a < b) is equal to pseudo if (unsigned int < unsigned char) .
Whenever a char is used in an expression, the whole promotion rules in C implicitly convert it to int . After that you
if (unsigned int < int) .
When an expression uses two integers with the same rank but with a different signature, the signed one gets implicitly converted to unsigned. This is determined by ordinary arithmetic conversions, as well as balancing.
So your first expression is converted to
if (unsigned int < unsigned int)
before anything is done.
In the second expression, if (a < (b ? b : c)) , which is equal to pseudo
if (unsigned int < (unsigned char ? unsigned char : unsigned char)) .
Integer promotions run on all characters, so they are implicitly converted to
if (unsigned int < (int ? int : int)) .
Then the strange, obscure rule for the conditional operator dictates that the 2nd and 3rd operator of the operator ?: must be balanced with the usual arithmetic transformations. In this case, they are already of the same type, so nothing happens. As a result, we get
if (unsigned int < int)
Balancing happens again, the result will be evaluated as
if (unsigned int < unsigned int)
When I compile it with Microsoft
When compiling with Microsoft, all bets are disabled, their compiler very poorly complies with the standard. Expect strange, illogical warnings.