Skip to content

Commit b380384

Browse files
committed
P1073R3 Immediate functions
1 parent 9326604 commit b380384

File tree

7 files changed

+125
-38
lines changed

7 files changed

+125
-38
lines changed

source/basic.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4803,6 +4803,8 @@
48034803
\item
48044804
a \grammarterm{constant-expression}\iref{expr.const},
48054805
\item
4806+
an immediate invocation\iref{expr.const},
4807+
\item
48064808
an \grammarterm{init-declarator}\iref{dcl.decl} or
48074809
a \grammarterm{mem-initializer}\iref{class.base.init},
48084810
including the constituent expressions of the initializer,

source/classes.tex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3712,7 +3712,11 @@
37123712
\begin{note}
37133713
Virtual functions support dynamic binding and object-oriented
37143714
programming. \end{note} A class that declares or inherits a virtual function is
3715-
called a \defnadj{polymorphic}{class}.
3715+
called a \defnadj{polymorphic}{class}.\footnote{If
3716+
all virtual functions are immediate functions,
3717+
the class is still polymorphic even though
3718+
its internal representation might not otherwise require
3719+
any additions for that polymorphic behavior.}
37163720

37173721
\pnum
37183722
If a virtual member function \tcode{vf} is declared in a class
@@ -4044,6 +4048,12 @@
40444048
function with a deleted definition.%
40454049
\indextext{function!virtual|)}
40464050

4051+
\pnum
4052+
A \tcode{consteval} virtual function shall not override
4053+
a virtual function that is not \tcode{consteval}.
4054+
A \tcode{consteval} virtual function shall not be overridden by
4055+
a virtual function that is not \tcode{consteval}.
4056+
40474057
\pnum
40484058
If an overriding function specifies contract conditions\iref{dcl.attr.contract},
40494059
it shall specify the same list of contract conditions as

source/compatibility.tex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1796,8 +1796,11 @@
17961796
to introduce constraints through a \grammarterm{requires-clause} or
17971797
a \grammarterm{requires-expression}. The \tcode{concept} keyword is
17981798
added to enable the definition of concepts\iref{temp.concept}.
1799+
The \tcode{consteval} keyword is added to
1800+
declare immediate functions\iref{dcl.constexpr}.
17991801
\effect
1800-
Valid ISO \CppXVII{} code using \tcode{concept} or \tcode{requires}
1802+
Valid ISO \CppXVII{} code
1803+
using \tcode{concept}, \tcode{consteval}, or \tcode{requires}
18011804
as an identifier is not valid in this International Standard.
18021805

18031806
\diffref{lex.operators}

source/declarations.tex

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
\terminal{friend}\br
254254
\terminal{typedef}\br
255255
\terminal{constexpr}\br
256+
\terminal{consteval}\br
256257
\terminal{inline}
257258
\end{bnf}
258259

@@ -269,9 +270,11 @@
269270
same type.
270271

271272
\pnum
272-
Each \grammarterm{decl-specifier} shall appear at most once in a complete
273-
\grammarterm{decl-specifier-seq}, except that
274-
\tcode{long} may appear twice.
273+
Each \grammarterm{decl-specifier}
274+
shall appear at most once in a complete \grammarterm{decl-specifier-seq},
275+
except that \tcode{long} may appear twice.
276+
The \tcode{constexpr} and \tcode{consteval} \grammarterm{decl-specifier}{s}
277+
shall not both appear in a \grammarterm{decl-specifier-seq}.
275278

276279
\pnum
277280
\indextext{ambiguity!declaration type}%
@@ -733,17 +736,21 @@
733736
\indextext{specifier!\idxcode{constexpr}}
734737

735738
\pnum
736-
The \tcode{constexpr} specifier shall be applied only to the definition of
737-
a variable or variable template or
738-
the declaration of a
739-
function or function template.
740-
A function or static data member declared with the \tcode{constexpr}
741-
specifier is implicitly an inline function or variable\iref{dcl.inline}.
739+
The \tcode{constexpr} specifier shall be applied only to
740+
the definition of a variable or variable template or
741+
the declaration of a function or function template.
742+
The \tcode{consteval} specifier shall be applied only to
743+
the declaration of a function or function template.
744+
A function or static data member
745+
declared with the \tcode{constexpr} or \tcode{consteval} specifier
746+
is implicitly an inline function or variable\iref{dcl.inline}.
742747
If any declaration of a function or function template has
743-
a \tcode{constexpr} specifier,
744-
then all its declarations shall contain the \tcode{constexpr} specifier. \begin{note} An
745-
explicit specialization can differ from the template declaration with respect to the
746-
\tcode{constexpr} specifier. \end{note}
748+
a \tcode{constexpr} or \tcode{consteval} specifier,
749+
then all its declarations shall contain the same specifier.
750+
\begin{note}
751+
An explicit specialization can differ from the template declaration
752+
with respect to the \tcode{constexpr} or \tcode{consteval} specifier.
753+
\end{note}
747754
\begin{note}
748755
Function parameters cannot be declared \tcode{constexpr}.\end{note}
749756
\begin{example}
@@ -773,12 +780,17 @@
773780
\end{example}
774781

775782
\pnum
776-
A \tcode{constexpr} specifier used in the declaration of a function that is not a
777-
constructor declares that
778-
function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. Similarly, a
779-
\tcode{constexpr} specifier used in
780-
a constructor declaration declares that constructor to be a
781-
\defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}.
783+
A \tcode{constexpr} or \tcode{consteval} specifier
784+
used in the declaration of a function that is not a constructor
785+
declares that function to be
786+
a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}.
787+
Similarly, a \tcode{constexpr} or \tcode{consteval} specifier used in
788+
a constructor declaration declares that constructor to be
789+
a \defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}.
790+
A function or constructor declared with the \tcode{consteval} specifier
791+
is called an \defn{immediate function}.
792+
A destructor, an allocation function, or a deallocation function
793+
shall not be declared with the \tcode{consteval} specifier.
782794

783795
\pnum
784796
\indextext{specifier!\idxcode{constexpr}!function}
@@ -948,8 +960,9 @@
948960
\end{itemize}
949961

950962
\pnum
951-
The \tcode{constexpr} specifier has no
952-
effect on the type of a constexpr function or a constexpr constructor. \begin{example}
963+
The \tcode{constexpr} and \tcode{consteval} specifier have no
964+
effect on the type of a constexpr function or a constexpr constructor.
965+
\begin{example}
953966
\begin{codeblock}
954967
constexpr int bar(int x, int y) // OK
955968
{ return x + y + x*y; }
@@ -1430,7 +1443,8 @@
14301443
\end{note}
14311444

14321445
\pnum
1433-
If the operand of a \grammarterm{decltype-specifier} is a prvalue,
1446+
If the operand of a \grammarterm{decltype-specifier} is a prvalue
1447+
and is not a (possibly parenthesized) immediate invocation\iref{expr.const},
14341448
the temporary materialization conversion is not applied\iref{conv.rval}
14351449
and no result object is provided for the prvalue.
14361450
The type of the prvalue may be incomplete or an abstract class type.
@@ -5868,9 +5882,9 @@
58685882

58695883
\pnum
58705884
An explicitly-defaulted function that is not defined as deleted may be declared
5871-
\tcode{constexpr} only if it would have been implicitly declared as
5872-
\tcode{constexpr}. If
5873-
a function is explicitly defaulted on its first declaration,
5885+
\tcode{constexpr} or \tcode{consteval} only
5886+
if it would have been implicitly declared as \tcode{constexpr}.
5887+
If a function is explicitly defaulted on its first declaration,
58745888
it is implicitly considered to be \tcode{constexpr} if the implicit
58755889
declaration would be.
58765890

source/expressions.tex

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,12 @@
12791279
\end{example}
12801280
\end{itemize}
12811281

1282+
\pnum
1283+
An \grammarterm{id-expression}
1284+
that denotes an immediate function\iref{dcl.constexpr}
1285+
shall appear as a subexpression of an immediate invocation or
1286+
in an immediate function context\iref{expr.const}.
1287+
12821288
\pnum
12831289
An \grammarterm{id-expression}
12841290
that denotes the specialization of a concept\iref{temp.concept}
@@ -1532,7 +1538,7 @@
15321538
\pnum
15331539
In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator},
15341540
each \grammarterm{decl-specifier}
1535-
shall either be \tcode{mutable} or \tcode{constexpr}.
1541+
shall be one of \tcode{mutable}, \tcode{constexpr}, or \tcode{consteval}.
15361542
\begin{note}
15371543
The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}.
15381544
\end{note}
@@ -1658,8 +1664,12 @@
16581664
The function call operator or any given operator template specialization
16591665
is a constexpr function if either
16601666
the corresponding \grammarterm{lambda-expression}{'s}
1661-
\grammarterm{parameter-declaration-clause} is followed by \tcode{constexpr}, or
1667+
\grammarterm{parameter-declaration-clause}
1668+
is followed by \tcode{constexpr} or \tcode{consteval}, or
16621669
it satisfies the requirements for a constexpr function\iref{dcl.constexpr}.
1670+
It is an immediate function\iref{dcl.constexpr}
1671+
if the corresponding \grammarterm{lambda-expression}{'s}
1672+
\grammarterm{parameter-declaration-clause} is followed by \tcode{consteval}.
16631673
\begin{note} Names referenced in
16641674
the \grammarterm{lambda-declarator} are looked up in the context in which the
16651675
\grammarterm{lambda-expression} appears. \end{note}
@@ -6802,8 +6812,12 @@
68026812
if the value is of pointer type, it contains
68036813
the address of an object with static storage duration,
68046814
the address past the end of such an object\iref{expr.add},
6805-
the address of a function,
6806-
or a null pointer value, and
6815+
the address of a non-immediate function,
6816+
or a null pointer value,
6817+
6818+
\item
6819+
if the value is of pointer-to-member-function type,
6820+
it does not designate an immediate function, and
68076821

68086822
\item
68096823
if the value is an object of class or array type,
@@ -6813,8 +6827,18 @@
68136827
\defnx{permitted result of a constant expression}{constant expression!permitted result of}
68146828
if it is an
68156829
object with static storage duration that is either not a temporary object or is
6816-
a temporary object whose value satisfies the above constraints, or it is a
6817-
function.
6830+
a temporary object whose value satisfies the above constraints, or
6831+
it is a non-immediate function.
6832+
\begin{example}
6833+
\begin{codeblock}
6834+
consteval int f() { return 42; }
6835+
consteval auto g() { return f; }
6836+
consteval int h(int (*p)() = g()) { return p(); }
6837+
constexpr int r = h(); // OK
6838+
constexpr auto e = g(); // ill-formed: a pointer to an immediate function is
6839+
// not a permitted result of a constant expression
6840+
\end{codeblock}
6841+
\end{example}
68186842

68196843
\pnum
68206844
\begin{note} Since this document
@@ -6835,15 +6859,31 @@
68356859
It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}.
68366860
\end{example} \end{note}%
68376861

6862+
\pnum
6863+
An expression or conversion is in an \defn{immediate function context}
6864+
if it is potentially evaluated and
6865+
its innermost non-block scope is
6866+
a function parameter scope of an immediate function.
6867+
An expression or conversion is an \defn{immediate invocation}
6868+
if it is an explicit or implicit invocation of an immediate function and
6869+
is not in an immediate function context.
6870+
An immediate invocation shall be a constant expression.
6871+
\begin{note}
6872+
An immediate invocation is evaluated even in an unevaluated operand.
6873+
\end{note}
6874+
68386875
\pnum
68396876
\indextext{expression!potentially constant evaluated}%
6840-
An expression is \defn{potentially constant evaluated}
6877+
An expression or conversion is \defn{potentially constant evaluated}
68416878
if it is:
68426879

68436880
\begin{itemize}
68446881
\item
68456882
a potentially-evaluated expression\iref{basic.def.odr},
68466883

6884+
\item
6885+
an immediate invocation,
6886+
68476887
\item
68486888
a \grammarterm{constraint-expression},
68496889
including one formed from the \grammarterm{constraint-logical-or-expression}
@@ -6881,4 +6921,21 @@
68816921
is of non-volatile const-qualified integral type or of reference type.
68826922
\end{itemize}
68836923

6924+
\begin{example}
6925+
\begin{codeblock}
6926+
struct N {
6927+
constexpr N() {}
6928+
N(N const&) = delete;
6929+
};
6930+
template<typename T> constexpr void bad_assert_copyable() { T t; T t2 = t; }
6931+
using ineffective = decltype(bad_assert_copyable<N>());
6932+
// \tcode{bad_assert_copyable<N>} is not needed for constant evaluation
6933+
// (and thus not instantiated)
6934+
template<typename T> consteval void assert_copyable() { T t; T t2 = t; }
6935+
using check = decltype(assert_copyable<N>());
6936+
// error: \tcode{assert_copyable<N>} is instantiated (because it is needed for constant
6937+
// evaluation), but the attempt to copy \tcode{t} is ill-formed
6938+
\end{codeblock}
6939+
\end{example}
6940+
68846941
\indextext{expression|)}

source/lex.tex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@
686686
\tcode{class} \\
687687
\tcode{concept} \\
688688
\tcode{const} \\
689+
\tcode{consteval} \\
689690
\tcode{constexpr} \\
690691
\columnbreak
691692
\tcode{const_cast} \\
@@ -703,8 +704,8 @@
703704
\tcode{extern} \\
704705
\tcode{false} \\
705706
\tcode{float} \\
706-
\columnbreak
707707
\tcode{for} \\
708+
\columnbreak
708709
\tcode{friend} \\
709710
\tcode{goto} \\
710711
\tcode{if} \\
@@ -719,9 +720,9 @@
719720
\tcode{operator} \\
720721
\tcode{private} \\
721722
\tcode{protected} \\
722-
\columnbreak
723723
\tcode{public} \\
724724
\tcode{register} \\
725+
\columnbreak
725726
\tcode{reinterpret_cast} \\
726727
\tcode{requires} \\
727728
\tcode{return} \\
@@ -735,10 +736,10 @@
735736
\tcode{switch} \\
736737
\tcode{template} \\
737738
\tcode{this} \\
738-
\columnbreak
739739
\tcode{thread_local} \\
740740
\tcode{throw} \\
741741
\tcode{true} \\
742+
\columnbreak
742743
\tcode{try} \\
743744
\tcode{typedef} \\
744745
\tcode{typeid} \\

source/templates.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6147,7 +6147,7 @@
61476147
member function of a class template, or
61486148
variable template
61496149
shall not
6150-
use the \tcode{inline} or \tcode{constexpr} specifiers.
6150+
use the \tcode{inline}, \tcode{constexpr}, or \tcode{consteval} specifiers.
61516151

61526152
\pnum
61536153
The syntax for explicit instantiation is:

0 commit comments

Comments
 (0)