Question Details

No question body available.

Tags

c

Answers (1)

Accepted Answer Available
Accepted Answer
March 30, 2025 Score: 6 Rep: 234,403 Quality: Expert Completeness: 80%

The reference to “level-2” is a reference to the row labeled “2” in the Precedence column in the preceding table.

This “level” is an invention of cppreference.com; it is not part of the C standard. (And so it is one reason cppreference.com is not a good reference.) The C standard does not specify precedences by levels or a table. Precedence is built into the formal grammar of the language.

In the formal C grammar, a cast-expression is one of:

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

A unary-expression is one of:

  • postfix-expression
  • ++ unary-expression
  • -- unary-expression
  • unary-operator cast-expression, where unary-operator is one of &, , +, -, ~, or !
  • sizeof unary-expression
  • sizeof ( type-name )
  • alignof ( type-name )

Comparing these to the cppreference.com table, we see its precedence level two items are all the operators of a unary-expression (omitting the operator-less postfix-expression) plus the cast operator. Therefore, the C standard’s unary-expression corresponds to all of cppreference.com’s level-2 operators except the cast. That is what cppreference.com is getting at with “level-2 non-cast”; taking its level-2 operators and removing the cast leaves the “unary” operators. (Cast is a unary operator,1 but it is not included in the unary-expression token in the formal C grammar. This is what prevents sizeof (int) p from being interpreted as sizeof ( (int ) p ) instead of (sizeof (int)) p, which is mentioned, but not explained, in cppreference.com’s note 2.)

cppreference.com’s statement that “Assignment operators' left operands must be unary (level-2 non-cast) expressions” refers to the fact that, in the C formal grammar, an assignment-expression is one of:

  • conditional-expression
  • unary-expression assignment-operator assignment-expression

Thus, the grammar requires that the left operand of an assignment operator be a unary-expression.

This is not the only requirement on the left operand of an assignment operator. C 2024 6.5.17.1 also states:

An assignment operator shall have a modifiable lvalue as its left operand.

This is not part of the formal grammar. It is stated separately as a constraint. So the left operand of an assignment operator must be a unary-expression and it must be a modifiable lvalue.

Footnote

1 Per Kernighan and Ritchie, The C Programming Language (second edition), 1988, page 45: “Finally, explicit type conversions can be forced (‘coerced’) in any expression, with a unary operator called a cast.”