The notation “constant-expression: conditional-expression” is only a specification of the syntax of a constant expression. The syntax describes the strings that may be a constant expression. In addition to satisfying the syntax, a constant expression must also satisfy the constraints listed in clause 6.6.
The fact that the C standard uses “constant-expression: conditional-expression” may be confusing. However, it would be exactly the same if the standard used “constant-expression: expression”, as I will show below. That is, any expression is a constant expression provided it follows not just the syntax for expressions but also the constraints listed in clause 6.6.
One example of a conditional expression is 3 < 4 ? 5 : 6
. This expression is also a constant expression, because it satisfies the constraints in clause 6.6. On the other hand, x < 4 ? 5 : 6
is also a conditional expression but is not a constant expression (assuming x
is the name of an object and is not a macro that gets replaced by a constant, et cetera).
The clause 6.6 tells you that a conditional expression may be a constant expression if it satisfies the constraints. Clause 6.5.15 shows that a conditional expression may be either a logical-OR-expression
or a logical-OR-expression ? expression : conditional-expression
. Continuing to work through the chain, a logical-OR-expression
may be the a logical-AND-expression
or may be an expression built with the logical OR operator, ||
. Although the name at each level is something like foo-expression
, each level is actually either the type of expression that came before or is an expression built with foo
. It would just be cumbersome to name them foo-expression-or-prior-type-of-expression
instead of just foo-expression
.
Thus, the grammar starts with the primaries, which are identifiers, constants, string literals, and one special thing I will discuss in a moment, and the grammar builds those primaries into more complicated expressions, adding the possibility of using each operator that C permits. Layering the grammar in this way defines the operator precedence, because the earlier expressions must be parsed before the later expressions, where possible.
The special thing in the primary is a parenthesized expression, ( expression )
. The expression
token is the end of the chain of definitions, defined in 6.5.17. This loops the grammar back; any expression can be placed in parentheses, which makes it a new primary
, and then operators can be applied to it.
Clause 6.6 could have stated that a constant-expression
is an expression
, and it would have the same effect as saying it is a conditional-expression
. This is because the constraints in 6.6 forbid assignment operators and comma operators. So, if we consider what an expression
could be, clause 6.5.17 says it can be either an assignment-expression
or expression , assignment-expression
. But the constraint prohibiting the comma operator prohibits the latter. Therefore, an expression
in a constant expression must be an assignment-expression
. Similarly, an assignment-expression
must be a conditional-expression
and not unary-expression assignment-operator assignment-expression
.