Reputation: 23
I am learning C++ and stumbled upong the following behaviour when using the ,
and ?:
operators. The conditional operator has a syntax like this E1 ? E2 : E3
, where E1, E2 and E3 are expressions[1],[2]. I started with this code:
#include <iostream>
using namespace std;
int main(){
int x = 20, y = 25;
x > y ? cout << "x > y\n" , cout << "x is greater than y" : cout << "x !> y\n", cout << "x is not greater than y";
return 0;
}
and outputs:
x !> y
x is not greater than y
which is the result I was expecting. But when I change the values to int x = 25, y = 20
so that x is greater than y, I get the following output:
x > y
x is greater than y
x is not greater than y
but I was expecting:
x > y
x is greater than y
so the final part of expression E3
is being computed even when the result of expression E1
was true
.
However, when I put E2 and E3 inside parenthesis, the output of the programm is as expected for both cases: when x > y and when x < y. According to [1], the comma ,
is on operator with operands E1 and E2 as in E1, E2
, which is an expression itself, by [1]. Based on this, I do not understand why the final part of expression E3 for the ?:
operator is being computed even when the expression E1
is true and both.
My questions are:
1) Am I correctly using the conditional operator ?:
?
2) What is the mechanism by which this unexpected result is happening?
3) Why does the use parenthesis solves the issue (or at least agrees with my expectation)?
I am working with: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)
Thank you very much.
[1]https://en.cppreference.com/w/cpp/language/expressions
[2]https://en.cppreference.com/w/cpp/language/operator_other
Upvotes: 2
Views: 181
Reputation: 496
For the sake of simplicity let's consider a statement that is easier to read:
foo ? a(), b() : c(), d();
The first operator we encounter is the conditional operator (§7.6.16):
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The second operand can be an expression and a(), b()
is a compound expression.
The third operand however can only be an assignment-expression (§7.6.19):
assignment-expression:
conditional-expression
yield-expression
throw-expression
logical-or-expression assignment-operator initializer-clause
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ^= |=
c(), d()
is not one of those but a comma-expression (§7.6.20/1):
expression:
assignment-expression
expression , assignment-expression
A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded-value expression. Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. [...]
So everything on the left side of the last comma operator in the whole statement is a discarded-value expression that gets computed (and its result discarded) before the right side of the comma operator.
Upvotes: 5