diff --git a/source/classes.tex b/source/classes.tex index 3110a48318..9ec3133300 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1092,13 +1092,6 @@ and, if the class is not abstract\iref{class.abstract}, its virtual base classes are called its \term{potentially constructed subobjects}. -\pnum -A defaulted special member function is -\indextext{member function!constexpr-compatible}% -\defnx{constexpr-compatible}{constexpr-compatible!defaulted special member function} -if the corresponding implicitly-declared special member function -would be a constexpr function. - \rSec2[class.ctor]{Constructors}% \rSec3[class.ctor.general]{General}% @@ -1314,7 +1307,7 @@ If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements -of a constexpr constructor\iref{dcl.constexpr}, the implicitly-defined +of a constexpr function\iref{dcl.constexpr}, the implicitly-defined default constructor is \keyword{constexpr}. Before the defaulted default constructor for a class is implicitly defined, @@ -1611,7 +1604,7 @@ its odr-use\iref{term.odr.use,class.temporary}. \end{note} If the implicitly-defined constructor would satisfy the requirements of a -constexpr constructor\iref{dcl.constexpr}, the implicitly-defined +constexpr function\iref{dcl.constexpr}, the implicitly-defined constructor is \keyword{constexpr}. \pnum @@ -1911,20 +1904,7 @@ to assign to an object of its class type), when it is needed for constant evaluation\iref{expr.const}, or when it is explicitly defaulted after its first declaration. -The implicitly-defined copy/move assignment operator is \keyword{constexpr} if -\begin{itemize} -\item -\tcode{X} is a literal type, and - -\item -the assignment operator selected to copy/move each direct base class subobject -is a constexpr function, and - -\item -for each non-static data member of \tcode{X} that is of class type (or array -thereof), the assignment operator selected to copy/move that member is a -constexpr function. -\end{itemize} +The implicitly-defined copy/move assignment operator is \keyword{constexpr}. \pnum Before the defaulted copy/move assignment operator for a class is @@ -2132,7 +2112,7 @@ \pnum A defaulted destructor is a constexpr destructor -if it satisfies the requirements for a constexpr destructor\iref{dcl.constexpr}. +if it satisfies the requirements for a constexpr function\iref{dcl.constexpr}. \pnum A destructor @@ -6503,35 +6483,6 @@ \tcode{a @ b} is a valid expression. \end{itemize} -\pnum -A defaulted comparison function is -\indextext{operator!comparison!constexpr-compatible}% -\defnx{constexpr-compatible}{constexpr-compatible!defaulted comparison operator} -if it -satisfies the requirements for a constexpr function\iref{dcl.constexpr} and -no overload resolution -performed when determining whether to delete the function -results in a usable candidate that is a non-constexpr function. -\begin{note} -This includes the overload resolutions performed: - -\begin{itemize} -\item -for an \tcode{operator<=>} whose return type is not \keyword{auto}, -when determining whether a synthesized three-way comparison is defined, - -\item -for an \tcode{operator<=>} whose return type is \keyword{auto} or -for an \tcode{operator==}, -for a comparison between an element of the expanded list of -subobjects and itself, or - -\item -for a secondary comparison operator \tcode{@}, -for the expression \tcode{x @ y}. -\end{itemize} -\end{note} - \pnum If the \grammarterm{member-specification} does not explicitly declare diff --git a/source/declarations.tex b/source/declarations.tex index 3cd7812e32..8e0bd83f4a 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -770,12 +770,6 @@ The definition of a constexpr function shall satisfy the following requirements: \begin{itemize} -\item -its return type (if any) shall be a literal type; - -\item -each of its parameter types shall be a literal type; - \item it shall not be a coroutine\iref{dcl.fct.def.coroutine}; @@ -816,78 +810,6 @@ \end{codeblock} \end{example} -\pnum -\indextext{specifier!\idxcode{constexpr}!constructor}% -The definition of a constexpr constructor -whose \grammarterm{function-body} is not \tcode{= delete} -shall additionally satisfy the following requirements: -\begin{itemize} - -\item -for a non-delegating constructor, every constructor selected to initialize non-static -data members and base class subobjects shall be a constexpr constructor; - -\item -for a delegating constructor, the target constructor shall be a constexpr -constructor. -\end{itemize} - -\begin{example} -\begin{codeblock} -struct Length { - constexpr explicit Length(int i = 0) : val(i) { } -private: - int val; -}; -\end{codeblock} -\end{example} - -\pnum -The definition of a constexpr destructor -whose \grammarterm{function-body} is not \tcode{= delete} -shall additionally satisfy the following requirement: -\begin{itemize} -\item - for every subobject of class type or - (possibly multi-dimensional) array thereof, - that class type shall have a constexpr destructor. -\end{itemize} - -\pnum -For a constexpr function or constexpr constructor -that is neither defaulted nor a template, -if no argument values exist such that -an invocation of the function or constructor could be an evaluated subexpression of a core -constant expression\iref{expr.const}, or, -for a constructor, an evaluated subexpression of -the initialization full-expression of some constant-initialized object\iref{basic.start.static}, -the program is ill-formed, no diagnostic required. -\begin{example} -\begin{codeblock} -constexpr int f(bool b) - { return b ? throw 0 : 0; } // OK -constexpr int f() { return f(true); } // ill-formed, no diagnostic required - -struct B { - constexpr B(int x) : i(0) { } // \tcode{x} is unused - int i; -}; - -int global; - -struct D : B { - constexpr D() : B(global) { } // ill-formed, no diagnostic required - // lvalue-to-rvalue conversion on non-constant \tcode{global} -}; - -constexpr int f(int x) { - static int n = x; - return n + x; // ill-formed, no diagnostic required - // all calls reach the static variable declaration -} -\end{codeblock} -\end{example} - \pnum If the instantiated template specialization of a constexpr function template @@ -896,10 +818,7 @@ function, that specialization is still a constexpr function, even though a call to such a function cannot appear in a constant -expression. If no specialization of the template would satisfy the -requirements for a constexpr function -when considered as a non-template function, the template is -ill-formed, no diagnostic required. +expression. \pnum An invocation of a constexpr function in a given context @@ -919,6 +838,10 @@ This can indirectly cause calls to \tcode{std::is_constant_evaluated} within an invocation of the function to produce a different value. \end{note} +\begin{note} +It is possible to write a constexpr function for which +no invocation satisfies the requirements of a core constant expression. +\end{note} \pnum The \keyword{constexpr} and \keyword{consteval} specifiers have no @@ -6249,18 +6172,15 @@ \end{itemize} \pnum -An explicitly-defaulted function that is not defined as deleted may be declared -\keyword{constexpr} or \keyword{consteval} only -if it is constexpr-compatible\iref{special,class.compare.default}. A function explicitly defaulted on its first declaration is implicitly inline\iref{dcl.inline}, -and is implicitly constexpr\iref{dcl.constexpr} if it is constexpr-compatible. +and is implicitly constexpr\iref{dcl.constexpr} +if it satisfies the requirements for a constexpr function. \pnum \begin{example} \begin{codeblock} struct S { - constexpr S() = default; // error: implicit \tcode{S()} is not \keyword{constexpr} S(int a = 0) = default; // error: default argument void operator=(const S&) = default; // error: non-matching return type ~S() noexcept(false) = default; // OK, despite mismatched exception specification diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 1362638193..6dabe092d6 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1760,7 +1760,7 @@ \defnxname{cpp_char8_t} & \tcode{201811L} \\ \rowsep \defnxname{cpp_concepts} & \tcode{202002L} \\ \rowsep \defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep -\defnxname{cpp_constexpr} & \tcode{202110L} \\ \rowsep +\defnxname{cpp_constexpr} & \tcode{202207L} \\ \rowsep \defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep \defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep \defnxname{cpp_consteval} & \tcode{201811L} \\ \rowsep