Why operator `?:` does not have priority? - c++

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

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.

Related

How a compiler make the defference between prefix and postix operators?

We know ++ and - - can be prefix or postfix and it depends on the position of the operand. for example :
++a prefix because the operand is on the right of the operator.
a++ postfix because the operand is on the left of the operator.
But In complicated expressions things become confusing. for example :
! - -a == ++ ! b I know to solve this i must apply the precedence rule but that depend on how i will consider the type of ++ , a postfix or prefix.
My question how can i decide if an operator a postfix or a prefix and more generaly how can i determine the operand of an unary operator ?
Don't.
Making some assumptions about type, your code should be:
!(-(-a)) == ++(!b)
Note the use of parentheses to obviate the need to even think about precedence.
Except this isn't a valid expression, because you can't increment an rvalue/temporary (assuming you aren't overloading operator! and returning a reference, which would be non-idiomatic and weird).
Also each side of the == should be split off into a variable declaration for clarity.
const bool isItHot = !a;
const bool isItCold = !b; // ignoring your ++ for now
return (isItHot == isItCold);
If you really need a tool to work out the precedence for you, Geordi can do it, or you can work it out from some documentation.

why parenthesis is unable to change c++ operator precedence in this case?

Here's my simple code:
int main()
{
int x = 5;
cout << (x++) << endl;
return 0;
}
the code above prints 5, not 6, even with the parenthesis, My thought is x = x + 1 be executed first before it is printed out? can anyone explain to me what's going on here? Thank you
edit: i definitely understand ++x guys, my question is about change operator precedence using ()
i definitely understand ++x guys, my question is about change operator precedence using ()
Operator precedence has nothing to do with this.
The misunderstanding probably isn't your fault: you've likely been mistaught. Your teacher(s) told you that an operand with a higher precedence, than some other operand, will be "executed first".
While this is a common explanation in schools, it is not true.
There are three things that can change the meaning of an expression in this sense:
Operator precedence
This is merely a set of rules that tell us, and tell the compiler, which operands go to which operator. Like, in 3 + 5 * 7, do we pass 3+5 to the multiplication operator, or do we pass 5*7 to the addition operator? It's about parsing.
Evaluation order
Each operand then needs to be evaluated to produce a value (e.g. 3+5 becomes 8, or 5*7 becomes 35). The rules on the order in which these evaluations happen are quite complicated in C++, more so than you might expect, but you usually don't have to worry about them unless you're doing crazy things in between sequence points (to borrow pre-C++11 parlance).
(This is the closest you'll get to a notion of "will be executed first".)
The meaning of the operator
This is where you're coming unstuck here. The meaning of the postfix increment operator x++ is "increment x, and evaluate to the old value". Period. Full stop.
It doesn't matter which operator precedence rules led to the expression x++ being evaluated (as opposed to some other interpretation of the symbols in your code): when it's evaluated, whenever it's evaluated, you get the old value for x.
The meaning of the prefix increment operator ++x, however, is "increment x, and evaluate to the new value", and that's the behaviour you want, so that's the code you should write.
Ultimately, what sequence of computer instructions actually produces this behaviour is completely up to the compiler, and can be surprising. You shouldn't worry about it, as long as the program's result is as specified in the standard.
So just forget about this "will be executed first" stuff; it's rubbish.
The expression (x++), with or without parentheses, evaluates to the previous value of x, and has the side-effect of increasing x.
If you want to see the effect of the increase then use the obscure
cout << (x++, x) << endl;
The value of x++ is the value of x before incrementing, no matter how many brackets you put. This has nothing to do with operator precendence, but this is just how post increment is defined.
edit: i definitely understand ++x guys, my question is about change operator precedence using ()
I already mentioned it, but to be clear: The value you see has little to do with operator precedence. With or without brackets ++ comes before <<. Even if this wasnt the case it would not change the value you get from x++. You could change order of the operators if you wrote
(cout << x)++ << endl;
but that would try to call ++ on the stream...
This is because x++ evaluates the value of x (5 in your case) and will increase its value after that....
what you are looking for is the pre-increment, also ++x
That is because, it is unrelated to operator precedence. The post-increment operator ++, as opposed to the pre-increment operator, increments its operand after its evaluation.
So what you see is normal and that behavior cannot be changed by introducing enclosing parenthesis around the variable. If you want the opposite to happen, then you should use the pre-increment operator like the following:
cout << ++x << endl;

Why can't I write cout<<a==b; but can write cout<<(a==b);

I know () has higher precedence than <<, and << has higher precedence than ==, but I want to know why I can't write cout<<a==b; yet can write cout<<(a==b); in C++.
How the compiler translates cout<<a==b; and then shows error?
<< has higher precedence than ==
as you can see here.
The statement
cout<<a==b
is equivalent to
(cout<<a)==b
The expression
cout<<a
returns a stream. This stream is compared to b. If there is no left shift operator for a stream and a or no comparing operator for a stream and b this causes a compiler error
cout<<a==b is similar to (cout<<a) == b as << has higher precedence over ==. Now cout<<a will be syntactically incorrect if the type of a is not supported for <<. Next, if a has an overload for the << operator, it will again be syntactically wrong as the == operator can't operate with std::stream and type of b unless b overloads this compare operator.
But in case of cout<<(a==b), a==b will result in a boolean value. As the << operator support boolean value it is a valid operation.
<< priority is higher than == so it's interpreted as (cout<<a)==b
but = has lower so you can do :
bool t = a == b

What is the "?" and ":" sequence actually called? [duplicate]

This question already has answers here:
What does the question mark character ('?') mean in C++?
(8 answers)
Closed 9 years ago.
This may be a bonehead question, but I cannot figure out what the ? exp : other_exp sequence is called.
Example:
int result = (true) ? 1 : 0;
I've tried using the Google machine, but it's hard to Googilize for something without knowing what it's called.
Thanks!
It is called the the conditional operator or alternativly the ternary operator as it a ternary operator (an operator which takes 3 operands (arguments)), and as it's usually the only operator, that does this.
It is also know as the inline if (iif), the ternary if or the question-mark-operator.
It is actualy a rather useful feature, as they are expressions, rather than statements, and can therefore be used, for instance in constexpr functions, assigments and such.
The C++ Syntax is;
logical-or-expression ? expression : assignment-expression
It's used as;
condition ? condition_is_true_expression : condition_is_false_expression
That is, if condition evaluates to true, the expression evaluates to condition_is_true_expression otherwise the expression evaluates to condition_is_false_expression.
So in your case, result would always be assigned the value 1.
Note 1; A common mistake that one makes while working with the conditional operator, is to forget that it has a fairly low operator precedence.
Note 2; Some functional languages doesn't provide this operator, as they have expression 'if...else' constructs, such as OCaml;
let value = if b then 1 else 2
Note 3; A funny use case, which is perfectly valid is using the conditional operator, to decide, which of two variable to assign a value to.
(condition ? x : y) = 1;
Notice the parentheses are necessary, as this is really what you get without them;
condition ? x : (y = 1);
They are called shorthand if-else or ternary operators.
See this article for more information.

syntactical use of comma operator in C++

I was going through someone elses code and I wasn't able to get the syntax of following
c = x<0 ? x = -x,'L':'R';
and
if(x) x--,putchar(c);
going by the symantics, it is clear that in the first, variable c is assigned 'L' or 'R'.And in the second, both x-- and putchar() are executed. But what exactly is the role of comma operator here??
But what exactly is the role of comma operator here?
In this case, code obfuscation. The original developer probably thought they were being clever.
The comma operator allows you to perform multiple actions in a single statement, but you are almost always better off using 2 statements. In those cases, it expands to:
if( x < 0 ) {
x = -x;
c = 'L';
} else {
c = 'R';
}
and
if(x) {
x--;
putchar(c);
}
The comma operator evaluates both expressions, and returns the value of the last.
The first expression does two things in one statement. If chooses 'L'
or 'R' and also sets x to its negative if 'L' is chosen.
The second expression (the part after the 'if') decrements x and then
puts a character. The meaning of this is unclear without more context.
Readability in both could be improved by using separate statements rather than the comma operator. The first tries to shoehorn an if statement into a conditional expression. But the second is already using an if statement, so it's unclear why the comma operator was chosen at all.
The role of the comma operator in that context is to allow using the conditional operator and write an assignment as part of the evaluation of one of the expressions.
In my opinion, this is just horrible style. An if statement would have better communicated the intent of that code, and would have hardly been less efficient.