constexpr and constant expressions are related in that constexpr tells us that a variable or function can be used where a constant expression can be used. This is what cppreference tell us:
The constexpr specifier declares that it is possible to evaluate the
value of the function or variable at compile time. Such variables and
functions can then be used where only compile time constant
expressions are allowed.
Constant expresions were present before C++11 and the rules governing constant expressions pre C++11 are covered in the same place in the C++03 draft standard(this is the earliest public draft available closest to C++03)1 as the draft C++11 standard which is section 5.19
Constant expressions, cppreference has a good summary on this topic in Constant expressions page but it is geared toward C++11 and C++14 and it hard to tell what applies pre C++11.
The standard pre C++11 lists where a constant expression is required, in first paragraph of 5.19
and it looks complete:
In several places, C++ requires expressions that evaluate to an
integral or enumeration constant: as array bounds (8.3.4,
5.3.4), as case expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2), as static member initializers (9.4.2),
and as integral or enumeration non-type template arguments (14.3).
the rest of paragraph 1 says:
An integral constant-expression can involve only literals of
arithmetic types (2.13, 3.9.1), enumerators, non-volatile const
variables or static data members of integral or enumeration types
initialized with constant expressions (8.5), non-type template
parameters of integral or enumeration types, and sizeof expressions.
Floating literals (2.13.3) can appear only if they are cast to
integral or enumeration types. Only type conversions to integral or
enumeration types can be used. In particular, except in sizeof
expressions, functions, class objects, pointers, or references shall
not be used, and assignment, increment, decrement, function-call, or
comma operators shall not be used.
and is followed by 5
more paragraphs that list further requirements.
In C++11 there is a list of where constant expressions can be used in paragraph 3 but it does not clarify where they are required. You probably have to search for the term constant expression to find all the places where it is required and usually there will be a phrase similar to:
shall be a constant expression
The shall being the important term since violating a shall requirement makes the program ill-formed.
Alternatively you can use Annex A
Grammar summary and search for constant-expression and that should cover all the places in the grammar where a constant expression is required, for example:
enumerator = constant-expression
Footnote:
- This answer to Where do I find the current C or C++ standard documents? has a complete list of the draft standards. Unfortunately the closest that is available to the public is from early
2005
. The earlier versions require authentication. As far as I know section 5.19
did not change much.