Why operator `?:` does not have priority?

After debugging I found that ternary operator ?: does not have priority. My question is why? I have the following code:

bool T = true;
cout << ((T == true) ? "true" : "false") << endl;
cout << (T == true) ? "true" : "false";

Output:

true
1

live demo: http://ideone.com/Tkvt9q

Answers


The conditional operator does have a precedence (albeit slightly complicated by its ternary nature); but that precedence is very low. Since it's lower than <<, the second is parsed as

(cout << (T == true)) ? "true" : "false";

streaming the boolean value of T == true, then evaluating (but ignoring) the expression "true". Most compilers will give a warning, if you enable a sensible set of warnings.

Here is a reference to the operator precedences, showing << with a higher precedence (7) than ?: (15): http://en.cppreference.com/w/cpp/language/operator_precedence


The conditional operator ? : does have precedence - it's number 15 in this table, lower than << and >> operators, which are number seven.

The rule that I follow to avoid mistakes like that is to use parentheses when in doubt. The rationale is simple: if you need to look up the priority in a table, good chances are that the readers of your code, including yourself, would need to do the same thing at some later time.


A lot of the other questions answer why you are seeing that behavior but they don't answer why the ternary operator has low priority.

The decision was made to have low ternary priority because we don't want the code

a<d ? 10 : 100

to end up meaning

a < (d ? 10 : 100) //BAD: not what we normally expect

we want it to mean

(a<d) ? 10 : 100 

Low priority for the ternary operator achieves this goal. This sort of thing is the whole reason for operator precedence that you find in languages. The goal is to make it convenient to write expressions that are expected to be normal in the language. Right? If not, it could just be left to right with parentheses. Which would be annoying to use and you'd quickly propose some sort of convenient operator precedence.


It is true that the ?: operator has no clearly defined priority. But the example in question does not really illustrate that. The relative priorities of << and ?: are rather unambiguous. All your example shows is that the priority of << is higher than the priority of ?:.

As for the more general issue of the priority of ?: operator... ?: operator has relatively convoluted format, compared to other operators: it has three non-uniform operands. Because of that non-uniformity the part before ? has different syntactic grouping properties than the parts after ?.

After all, "priorities" are a derivative trick invented to simplify visualization and memorization of syntactic groupings defined by the grammar. Not all C++ operators conform to that trick though. The ?: operator happens to be the one that does not, which is why a properly written priority table will typically have a side note for ?: operator, explaining its unusual properties. Again, the part before the ? has different priority than the parts after the ?, which is why it is impossible to properly place the ?: operator into a linear table of priorities.

Unless I'm forgetting something, the ?: operator is the only operator without a straightforwardly definable priority.

P.S. Things with ?: operator were even worse in C. C++-related changes to the grammar made ?: to conform better to the idea of linear priority.


Like the other answers note, the << operator has higher precedence than the ? operator. Here is my opinion on why it is so.

Using bit-shift (<<) with the choice operator makes sense; for example

(T == true) ? (whatever << 1) : (whatever << 2)
(T == true) ? whatever << 1 : whatever << 2 // same as above

When the designers of C++ invented operator overloading, they decided to reuse the bit-shift operator << as a streaming operator. Had they introduced another, completely new streaming operator (e.g. <<<), it would get very low precedence, so the code would work as expected:

cout <<< (T == true) ? "true" : "false";

However, introducing a new operator just for it to be overloaded would undermine the idea of usefulness of operator overloading, which was a fascinating idea back then. So they decided to use an old (existing) operator.


The ternary conditional operator does have a precedence, except that it's at the bottom of the list (value 15). Only throw and , (comma) have a lesser precedence. See this reference for C++ Operator Precedence.


because of brackets, firstly statement (T == true) is evaluated, then comes the left shift operator and 1 which was evaluated earlier is sent to cout. later, the ternary operator evaluates "true" but it is ignored.

all in all, ternary operator has precedence, but one of the lowest.


Need Your Help

How to prevent value changed events from firing on form initialization in .NET?

.net winforms events

Consider a simple .NET form with a couple of radio buttons and a checkbox.

What does the @Valid annotation indicate in Spring?

java spring spring-mvc spring-annotations

In the following example, the ScriptFile parameter is marked with an @Valid annotation.