Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Constant expressions" prior to C++11

The constexpr keyword was introduced in C++11, as (I think) was the corresponding idea of "constant expressions." However, this concept was implicitly present in C++98/c++03, since array declarations require a constant expression:

// valid:
int a[sizeof(int)];
int b[3+7];
int c[13/4];
const int n = 3;
int d[n];
// invalid:
int m = 4;
int e[m];

There are other "constant expressions", i.e., expressions that can be (and/or must be) evaluated at compile-time; one example is template arguments.

For pre-C++11, do the following exist, either in the C++98/03 standards or elsewhere?

  • A complete list of syntactic constructs requiring constant expressions (e.g. array declarations and template instantiations)
  • The rules governing such constant expressions (presumably this would just be a mapping from the items in the above list to their definitions in the standard)
like image 778
Kyle Strand Avatar asked Sep 24 '14 19:09

Kyle Strand


People also ask

What is a constant expression in C?

A constant expression gets evaluated at compile time, not run time, and can be used in any place that a constant can be used. The constant expression must evaluate to a constant that is in the range of representable values for that type.

Should I use Constexpr instead of const?

const can only be used with non-static member functions whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.

What does constant expression mean?

A constant expression is an expression that can be evaluated at compile time. Constants of integral or enumerated type are required in several different situations, such as array bounds, enumerator values, and case labels. Null pointer constants are a special case of integral constants.

What does Constexpr mean in C++?

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 (provided that appropriate function arguments are given).


1 Answers

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:

  1. 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.
like image 62
Shafik Yaghmour Avatar answered Oct 10 '22 18:10

Shafik Yaghmour