Jason Merrill
Revision 10

static_assert and list-initialization in constexpr functions


This paper provides drafting to resolve core issues 837 and 898.

898. Declarations in constexpr functions

Section: 7.1.5  [dcl.constexpr]    

According to 7.1.5 [dcl.constexpr] paragraph 3, no declarations are permitted in the body of a constexpr function. This seems overly restrictive. At least three kinds of declarations would seem to be helpful in writing such functions: static_assert, typedef and alias declarations, and local automatic variables initialized with constant expressions. (Similar considerations apply to lambdas in which the lambda-return-type-clause is omitted.)

837. Constexpr functions and return braced-init-list

Section: 7.1.5  [dcl.constexpr]    

The body of a constexpr function is required by 7.1.5 [dcl.constexpr] paragraph 3 to be of the form

However, there does not seem to be any good reason for prohibiting the alternate return syntax involving a braced-init-list. The restriction should be removed.

Proposed Resolution

Change 6.6.3 [stmt.return] paragraph 2 as follows:

A return statement without an expression with neither an expression nor a braced-init-list can be used only in functions that do not return a value...
  • its function-body shall be a compound-statement of the form
      { return expression ; }
    that contains only
  • every constructor call and implicit conversion used in converting expression to the function return type initializing the return value (6.6.3 [stmt.return], 8.5 [dcl.init]) shall be one of those allowed in a constant expression (5.19 [expr.const]).

  • 7.1.5/4:
  • the compound-statement of its function-body shall be emptycontain only
  • 7.1.5/5:
    Function invocation substitution for a call of a constexpr function or of a constexpr constructor means implicitly converting each argument expression to the corresponding parameter type as if by copy-initialization [ Footnote: ... --end footnote], substituting that converted expression for each use of the corresponding parameter in the function-body, and, for constexpr functions, implicitly converting the resulting returned expression or braced-init-list to the return type of the function as if by copy-initialization. Such substitution does not change the meaning. [ Example: ... --end example]

    For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19 expr.const), the program is ill-formed; no diagnostic required. For a constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required.