In short, const
doesn't mean “constant expression” (the const
keyword is a little confusing IMO). Precisely,
C11 6.8.4.2 p.2 (emph. mine)
The expression of each case label shall be an integer constant expression […]
So, the question is, what an integer constant expression is; C11 addresses this in 6.6:
Description (p. 2)
A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.
The Constraints section (p. 3/4) goes on:
Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.115)
Each constant expression shall evaluate to a constant that is in the range of representable values for its type.
And the footnote:
115) The operand of a sizeof or _Alignof operator is usually not evaluated (6.5.3.4).
Semantics (p. 5/6)
An expression that evaluates to a constant is required in several contexts. […] An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof
expressions whose results are integer constants, _Alignof
expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof
or _Alignof
operator. [emph. mine, omitted footnotes 116 and 117]
The emphasized list of allowed operands doesn't contain variables (at least not in general, sizeof VALUE_2
would be OK), no matter if they are const
-qualified or not (you mentioned C++ in your question; if you're interested, have a look at C++11's constexpr
).
And (ibid. p. 10)
An implementation may accept other forms of constant expressions.
I quoted C11; C99 is basically the same (but doesn't have the _Alignof
operator), with the same sections.
HTH