0

Please consider the below example

struct Test{
   Test(int){}
};
int main(){
  int a = 0;
  int b = 0;
  bool c = true;
  Test t = c?a:b = 1;
}

All compilers agree that this statement Test t = c?a:b = 1; is well-formed. However I have doubt for this result.

First, for this text Test t = c?a:b = 1;, it's a declaration, which has an initializer, such an initializer has the form:

brace-or-equal-initializer:

= initializer-clause

initializer-clause is either

assignment-expression or
braced-init-list

In my example, the initializer-clause should be assignment-expression which is denoted by text c?a:b = 1, and an valid assignment-expression shall satisfy one of these grammars:

assignment-expression

  • conditional-expression
  • logical-or-expression assignment-operator initializer-clause
  • throw-expression

For this text c?a:b = 1, the assignment-operator is = and the initializer-clause is 1 which is literal(one kind of primary-expression, i.e, an valid initializer-clause).

What I can't understand is here, the left part of = shall be an logical-or-expression. However in my example, the left part is c?a:b which is a conditional expression. In other words, I can't find any valid form in grammar tree of logical-or-expression which can denote c?a:b. Namely, conditional-expression is not subsumed into logical-or-expression.

That means, this assignment-expression c?a:b = 1 should have be ill-formed. But all compilers say that it's well-formed, how to interpret this? why the text c?a:b = 1 can be as a valid assignment-expression?

xmh0511
  • 7,010
  • 1
  • 9
  • 36
  • 1
    `c?a:b = 1` **doesn't** match *logical-or-expression* *assignment-operator* *initializer-clause*, it matches *conditional-expression* – Caleth Oct 09 '20 at 14:07
  • @Caleth you're right. the precedence of the conditional-expression is higher than that of assignment-expression. So `c?a:b = 1` is equivalent to `c?a:(b = 1)` rather than `(c?a:b) = 1`. – xmh0511 Oct 10 '20 at 01:37
  • 1
    That's backwards: we say that expressions have precedence based on the rules of the grammar. If there wasn't *conditional-expression*, `c?a:b = 1` wouldn't be legal C++. There's no production of *logical-or-expression* that can match `c?a:b` – Caleth Oct 10 '20 at 09:52
  • @Caleth Exactly. – xmh0511 Oct 12 '20 at 01:38

0 Answers0