CWG Issue 2490 (original) (raw)

This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-11-05


2490. Restrictions on destruction in constant expressions

Section: 7.7 [expr.const]Status: CD6Submitter: Jiang AnDate: 2021-05-04

[Accepted as a DR at the October, 2021 meeting.]

According to 7.7 [expr.const] paragraph 6,

For the purposes of determining whether an expression E is a core constant expression, the evaluation of a call to a member function ofstd::allocator as defined in 20.2.10.2 [allocator.members], where T is a literal type, does not disqualify E from being a core constant expression, even if the actual evaluation of such a call would otherwise fail the requirements for a core constant expression. Similarly, the evaluation of a call tostd::destroy_at, std::ranges::destroy_at,std::construct_at, or std::ranges::construct_at does not disqualify E from being a core constant expression unless:

There are, however, no specific restrictions in 7.7 [expr.const] regarding destructor or pseudo-destructor calls. In particular, a constexpr destructor can be called for any object, regardless of how it was constructed or the start of its lifetime, and similarly for pseudo-destructor calls. This seems inconsistent.

If those restrictions are added, would the specific restrictions on library destruction facilities still be needed?

Notes from the August, 2021 teleconference:

CWG agreed that since trivial destructors and pseudo-destructors are now considered to end the lifetime of the object for which they are called, they should be prohibited from being invoked for a runtime object in a constant expression.

Proposed resolution (August, 2021):

  1. Change 7.7 [expr.const] paragraph 5 as follows:

An expression E is a _core constant expression_unless the evaluation of E, following the rules of the abstract machine (6.10.1 [intro.execution]), would evaluate one of the following:

  1. Change 7.7 [expr.const] paragraph 6 as follows, merging the single remaining bulleted item into the running text of the paragraph:

For the purposes of determining whether an expression E is a core constant expression, the evaluation of a call to a member function ofstd::allocator as defined in 20.2.10.2 [allocator.members], where T is a literal type, does not disqualify E from being a core constant expression, even if the actual evaluation of such a call would otherwise fail the requirements for a core constant expression. Similarly, the evaluation of a call tostd::destroy_at, std::ranges::destroy_at, std::construct_at,or std::ranges::construct_at does not disqualify E from being a core constant expression unless: