Skip to content

[class], [utility], [time] remove redundant constexpr-suitable references to determine constexpr-ness of constructors/destructors #8108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1440,8 +1440,7 @@
\grammarterm{compound-statement}.
If that user-written default constructor would be ill-formed,
the program is ill-formed.
If that user-written default constructor would be constexpr-suitable\iref{dcl.constexpr},
the implicitly-defined
The implicitly-defined
default constructor is \keyword{constexpr}.
Before the defaulted default constructor for a class is
implicitly defined,
Expand Down Expand Up @@ -1726,8 +1725,7 @@
The copy/move constructor is implicitly defined even if the implementation elided
its odr-use\iref{term.odr.use,class.temporary}.
\end{note}
If an implicitly-defined\iref{dcl.fct.def.default} constructor would be constexpr-suitable\iref{dcl.constexpr},
the implicitly-defined
The implicitly-defined\iref{dcl.fct.def.default}
constructor is \keyword{constexpr}.

\pnum
Expand Down Expand Up @@ -2223,8 +2221,7 @@
\defnx{non-trivial}{destructor!non-trivial}.

\pnum
A defaulted destructor is a constexpr destructor
if it is constexpr-suitable\iref{dcl.constexpr}.
A defaulted destructor is a constexpr destructor.

\pnum
Before a
Expand Down
8 changes: 1 addition & 7 deletions source/time.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,7 @@

public:
// \ref{time.duration.cons}, construct/copy/destroy
constexpr duration() = default;
duration() = default;
template<class Rep2>
constexpr explicit duration(const Rep2& r);
template<class Rep2, class Period2>
Expand Down Expand Up @@ -1304,12 +1304,6 @@
Members of \tcode{duration} do not throw exceptions other than
those thrown by the indicated operations on their representations.

\pnum
The defaulted copy constructor of \tcode{duration} shall be a
constexpr function if and only if the required initialization
of the member \tcode{rep_} for copy and move, respectively, would
be constexpr-suitable\iref{dcl.constexpr}.

\pnum
\begin{example}
\begin{codeblock}
Expand Down
17 changes: 0 additions & 17 deletions source/utilities.tex
Original file line number Diff line number Diff line change
Expand Up @@ -809,12 +809,6 @@
the element-wise operations specified to be called for that operation
throws an exception.

\pnum
The defaulted move and copy constructor, respectively, of \tcode{pair}
is a constexpr function if and only if all required element-wise
initializations for move and copy, respectively,
would be constexpr-suitable\iref{dcl.constexpr}.

\pnum
If \tcode{(is_trivially_destructible_v<T1> \&\& is_trivially_destructible_v<T2>)}
is \tcode{true}, then the destructor of \tcode{pair} is trivial.
Expand Down Expand Up @@ -1797,14 +1791,6 @@
For each \tcode{tuple} constructor, an exception is thrown only if the construction of
one of the types in \tcode{Types} throws an exception.

\pnum
The defaulted move and copy constructor, respectively, of
\tcode{tuple} is a constexpr function if and only if all
required element-wise initializations for move and copy, respectively,
would be constexpr-suitable\iref{dcl.constexpr}.
The defaulted move and copy constructor of \tcode{tuple<>} are
constexpr functions.

\pnum
If \tcode{is_trivially_destructible_v<$\tcode{T}_i$>} is \tcode{true} for all $\tcode{T}_i$,
then the destructor of \tcode{tuple} is trivial.
Expand Down Expand Up @@ -5773,9 +5759,6 @@

\pnum
\remarks
This function is \keyword{constexpr} if and only if the
value-initialization of the alternative type $\tcode{T}_0$
would be constexpr-suitable\iref{dcl.constexpr}.
Copy link
Member

@jwakely jwakely Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change in particular seems to be removing an imperfect attempt to specify something which is not easily deducible from other normative wording.

This says that whether the constructor is a constant expression relies only on initialisation of that one alternative, and nothing else. The equivalent wording for duration and pair and tuple does the same, but it's arguably easier to deduce that from the exposition-only members of those types. Here I think we're actually losing useful wording.

Maybe the correct fix is to say an evaluation of this constructor is a constant expression if...

But just removing these words doesn't seem like an improvement to me. Until we resolve the much larger "what does the library mean when it says something is a constexpr function" issue this wording is not redundant and is load-bearing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need to say that? This what you are saying is conditional constexpr, but now constexpr is just an opt-in to constant-evaluation, it's not guarantee, you can just "this function is marked constexpr", and if any of the subtype constructors is not, it will fail to call it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need specify conditional constexpr only for these types (pair/tuple/time_duration) it feels like a redundancy and language wording is enough. Especially with templates you must explicitly aim it on make something constexpr not evaluatable.

Copy link
Member

@Eisenwave Eisenwave Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional constexpr described in these Remarks would currently always be present, and it's an improvement of the status quo to make it unconditionally constexpr. The issue described is likely broad enough to warrant a paper, so it seems a bit silly to hold back this correct editorial change.

What seems to be missing here is a Constant When specification, but that would require non-editorial changes. It also seems to me that there's a much broader issue of under-specifying in the standard library when calls to constexpr functions are constant expressions and not. For example, we don't say anywhere in [algorithms] that running constexpr algorithms is a constant expression only if every operation performed on the iterators is a constant expression, do we? Should that be specified for each algorithm or as blanket wording? Big questions ...

Can't we just address that as blanket wording in [library] anyway?

Copy link
Member

@Eisenwave Eisenwave Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this particular paragraph, it is stated that the variant value-initializes the first alternative, so it seems clear enough that it wouldn't produce a constant expression if that value-initialization isn't a constant expression.

That doesn't guarantee that the constexprness relies only on the constexprness of that initialization, but the same applies to basically anything that's not specified as "Effects Equivalent to:" We never say that std::countl_zero doesn't use goto internally, and yet it's marked constexpr, and yet it always produces a constant expression in practice.

If that is okay, then we shouldn't need to point out when exactly std::variant initialization is a constant expression either, since we do that basically nowhere in the standard library and it seems like a big effort to attempt consistency.

The exception specification is equivalent to
\tcode{is_nothrow_default_constructible_v<$\tcode{T}_0$>}.
\begin{note}
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy