Search code examples
c++language-lawyerexpressioninitializer

How could be an initializer expression is "assignment-expression" by the grammer?


I have this sample of code:

struct S {};

S s = S();

Per my understanding, I see that s = S() in the declaration S s = S() is an init-declarator where s is a declarator and = S() is an initializer.

Also, I see that the initializer (= S()) is a brace-or-equal-initializer which is "= initializer-clause". This means finally that S() is an initializer-clause.

By the grammar, an initializer-clause is either an assignment-expression or a braced-init-list. Indeed, S() might not be a braced-init-list, but it may be an assignment-expression.

If my analysis is correct so far, I have a question here:

How S() is an assignment-expression? Where is the assignment-operator in expression S()?

In other words, the grammar of assignment-expression is:

assignment-expression:
      conditional-expression
      yield-expression
      throw-expression
      logical-or-expression assignment-operator initializer-clause

how S() could be one of the above?

Similarly, the grammar of a throw-expression is

throw-expression:
    throw assignment-expression

how S() in statement throw S(); is an assignment-expression?


Solution

  • How S() is an assignment-expression?

    Because it matches the first option conditional-expression as shown below. Note the emphasized part in each section/part and that at the end we reach to simple-type-specifier ( expression-listopt ) which is S().

    assignment-expression:

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

    Next, we go to conditional expression:

    conditional-expression:

    • logical-or-expression
    • logical-or-expression ? expression : assignment-expression

    Next, to logical-or-expression:

    logical-or-expression:

    • logical-and-expression
    • logical-or-expression || logical-and-expression

    Next, to logical-and-expression:

    logical-and-expression:

    • inclusive-or-expression
    • logical-and-expression && inclusive-or-expression

    From inclusive-or-expression:

    inclusive-or-expression:

    • exclusive-or-expression
    • inclusive-or-expression | exclusive-or-expression

    Next, exclusive-or-expression

    exclusive-or-expression:

    • and-expression
    • exclusive-or-expression ^ and-expression

    Now to and-expression

    and-expression:

    • equality-expression
    • and-expression & equality-expression

    From relational-operator

    equality-expression:

    • relational-expression
    • equality-expression == relational-expression
    • equality-expression != relational-expression

    Next from relational-expression

    relational-expression:

    • compare-expression
    • relational-expression < compare-expression
    • relational-expression > compare-expression
    • relational-expression <= compare-expression
    • relational-expression >= compare-expression

    Next to compare-expression

    compare-expression:

    • shift-expression
    • compare-expression <=> shift-expression

    Next to shift-expression

    shift-expression:

    • additive-expression
    • shift-expression << additive-expression
    • shift-expression >> additive-expression

    Next additive-expression

    additive-expression:

    • multiplicative-expression
    • additive-expression + multiplicative-expression
    • additive-expression - multiplicative-expression

    Next to multiplicative-expression

    multiplicative-expression:

    • pm-expression
    • multiplicative-expression * pm-expression
    • multiplicative-expression / pm-expression
    • multiplicative-expression % pm-expression

    Next to pm-expression

    pm-expression:

    • cast-expression
    • pm-expression .* cast-expression
    • pm-expression ->* cast-expression

    Next to cast-expression

    cast-expression:

    • unary-expression
    • ( type-id ) cast-expression

    Next to unary-expression

    unary-expression:

    • postfix-expression
    • unary-operator cast-expression
    • ++ cast-expression
    • -- cast-expression
    • await-expression
    • sizeof unary-expression
    • sizeof ( type-id )
    • sizeof ... ( identifier )
    • alignof ( type-id )
    • noexcept-expression
    • new-expression
    • delete-expression

    Finally we reach postfix-expression

    postfix-expression:

    • primary-expression
    • postfix-expression [ expression-listopt ]
    • postfix-expression ( expression-listopt )
    • simple-type-specifier ( expression-listopt )
    • typename-specifier ( expression-listopt )
    • simple-type-specifier braced-init-list
    • typename-specifier braced-init-list
    • postfix-expression . templateopt id-expression
    • postfix-expression -> templateopt id-expression
    • postfix-expression ++
    • postfix-expression --
    • dynamic_cast < type-id > ( expression )
    • static_cast < type-id > ( expression )
    • reinterpret_cast < type-id > ( expression )
    • const_cast < type-id > ( expression )
    • typeid ( expression )
    • typeid ( type-id )