简体   繁体   中英

Using the comma operator with the conditional operator

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 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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM