1

So the operator precedence of the ternary operator in C seems truly bizarre to me. Case in point:

#include <stdio.h>

int main ()
{
   int i=5;
   int j=6;
   int k=7;
   printf("A: %d\n", i+j+(k!=7)?1:11); //prints 1
   printf("B: %d\n", i+j+((k!=7)?1:11)); //prints 22
   return 0;
}

This seems similar to the question here:
C++ ternary conditional and assignment operator precedence
Ternary operator evaluation order

As a clarification, I understand that the parentheses make it work, as my comments in my original post indicated...

I'm just wondering why the language authors would pick an evaluation method that is so likely to trick people up, when the first statement seems like it could be formatted compiler-wise to be valid.

But those question deals with operators on the left-hand side or within class members, where as this weird behavior occurs on the RHS.

Community
  • 1
  • 1
Jason R. Mick
  • 5,177
  • 4
  • 40
  • 69
  • 7
    Moral of this story: use parentheses. – Richard J. Ross III Mar 19 '12 at 00:10
  • Yep, found that out the hard way, just wondering why. :) To me if the compiler sees `?` why can't it take whatever was before it, within `()` for a more complicated statement, or in the simplest case a single statement without the parentheses... That would seemingly make more sense... – Jason R. Mick Mar 19 '12 at 00:13
  • 2
    Jason, everyone knows that computers are made by mad scientists in labs, so of course they don't make sense! – Richard J. Ross III Mar 19 '12 at 00:16
  • Haha, I guess... hopefully this post saves someone some trouble. I made the mistake of trying the ternary operator in a large code and it really gave a headache trying to track down why I was getting crazy segfaults. :) Ah well, all's well that ends well! – Jason R. Mick Mar 19 '12 at 00:19

2 Answers2

6

What is weird here? The first part is interpreted as:

(11 + (k != 7)) ? 1 : 11

and the second is interpreted as

 11 + ((k !=7) ? 1 :11)

The first is caused by the precedence rules (binary arithmetic has higher precedence than the ternary operator) and the second circumvents the precedence rules through grouping the expression with parenthesis.

Your edit asks for the reasons and one can usually only guess at those unless someone on the C committee who was present at the time comes around to help. My guess would be that it is much more common to use a complex expression and ask for its truth value than using the ternary operator to determine the value of an expression in arithmetic. Something like this comes to mind:

return (froble() + 3) == 0 ? 23 : 5; // parens for sanity but works without

if this would be interpreted as return (froble() + 3) == 5; I would be truly shocked.

pmr
  • 58,701
  • 10
  • 113
  • 156
  • I get that, but it seems to me that precedence rule will burn a lot of people the first time they try the ternary... To me `(...)?` for complex ops and then `...?` for one-statement checks would make more sense and be kinder to those exploring the language for the first time. – Jason R. Mick Mar 19 '12 at 00:17
  • Well, @pmr is right, though, at least insofar as established convention goes. An experienced C programmer will long ago have trained his eye to impute low precedence to the ?: ternary, and it is accepted programming style to omit the parentheses around the condition. – thb Mar 19 '12 at 00:20
  • 1
    @JasonR.Mick I tried providing an example where your interpretation would lead to horrible consequences and the interpretation of the standard to a lot cleaner code. – pmr Mar 19 '12 at 00:21
  • @pmr interesting, thanks for the example, I guess it probably makes sense from that perspective... – Jason R. Mick Mar 19 '12 at 00:24
0

One should pick a very high or very low precedence, and one or the other will be surprising to someone who makes the wrong assumption.

A useful reason for choosing low precedence is that it means that the operator functions like an if .. then .. else .. construct without any braces, which might mean less work for compiler writers (who might use the same code to handle both), and straightforward refactoring by coders who understand the precedence.

In practice, the language probably standardised whatever precedence was the most popular usage in code written in the pre-standardization era.

mabraham
  • 2,806
  • 3
  • 28
  • 25