Can a class with consteval constructor be created on heap in C++?

Viewed 279

In the following code struct A has immediate function default constructor, and an object of the struct is created in the dynamic memory be means of new A{}:

struct A {       
    consteval A() {}
};

int main() {
    new A{};
}

Only Clang accepts it.

GCC complains

error: the value of '<anonymous>' is not usable in a constant expression
    6 |     new A{};
      |           ^
note: '<anonymous>' was not declared 'constexpr'

And MSVC does as well:

error C7595: 'A::A': call to immediate function is not a constant expression

Demo: https://gcc.godbolt.org/z/6Px5WYGzd

Which compiler is right here?

1 Answers

Which compiler is right here?

Invoking a consteval constructor with new is ill-formed.
MSVC and GCC are right to reject it; clang is wrong as a diagnostic is required.


struct A { consteval A() {} };

consteval makes A::A() an immediate function1.

An immediate function can only be called from2,3:

  • another immediate function, or
  • a consteval if statement, or
  • a constant expression4.

new A{} is none of the above.


1) [dcl.constexpr]/2

A constexpr or consteval specifier used in the declaration of a function declares that function to be a constexpr function. A function or constructor declared with the consteval specifier is called an immediate function.

2) [expr.prim.id.general]/4

A potentially-evaluated id-expression that denotes an immediate function shall appear only
(4.1) as a subexpression of an immediate invocation, or
(4.2) in an immediate function context.

3) [expr.const]/13

An expression or conversion is in an immediate function context if it is potentially evaluated and either:
(13.1) its innermost enclosing non-block scope is a function parameter scope of an immediate function, or
(13.2) its enclosing statement is enclosed ([stmt.pre]) by the compound-statement of a consteval if statement ([stmt.if]).

An expression or conversion is an immediate invocation if it is a potentially-evaluated explicit or implicit invocation of an immediate function and is not in an immediate function context.
An immediate invocation shall be a constant expression.

4) [expr.const]/11.2

A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints:
(11.2) if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object ([expr.add]), the address of a non-immediate function, or a null pointer value,

Related