Skip to content

Commit 0994313

Browse files
jensmaurerzygoloid
authored andcommitted
P1073R3 Immediate functions
1 parent 5842e7e commit 0994313

File tree

8 files changed

+149
-48
lines changed

8 files changed

+149
-48
lines changed

source/basic.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,6 +4845,8 @@
48454845
\item
48464846
a \grammarterm{constant-expression}\iref{expr.const},
48474847
\item
4848+
an immediate invocation\iref{expr.const},
4849+
\item
48484850
an \grammarterm{init-declarator}\iref{dcl.decl} or
48494851
a \grammarterm{mem-initializer}\iref{class.base.init},
48504852
including the constituent expressions of the initializer,

source/classes.tex

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

37143718
\pnum
37153719
If a virtual member function \tcode{vf} is declared in a class
@@ -4041,6 +4045,12 @@
40414045
function with a deleted definition.%
40424046
\indextext{function!virtual|)}
40434047

4048+
\pnum
4049+
A \tcode{consteval} virtual function shall not override
4050+
a virtual function that is not \tcode{consteval}.
4051+
A \tcode{consteval} virtual function shall not be overridden by
4052+
a virtual function that is not \tcode{consteval}.
4053+
40444054
\pnum
40454055
If an overriding function specifies contract conditions\iref{dcl.attr.contract},
40464056
it shall specify the same list of contract conditions as

source/compatibility.tex

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,15 +1795,28 @@
17951795
\diffref{lex.key}
17961796
\change New keywords.
17971797
\rationale Required for new features.
1798-
The \tcode{requires} keyword is added
1799-
to introduce constraints through a \grammarterm{requires-clause} or
1800-
a \grammarterm{requires-expression}. The \tcode{concept} keyword is
1801-
added to enable the definition of concepts\iref{temp.concept}.
1798+
\begin{itemize}
1799+
\item
18021800
The \tcode{char8_t} keyword is added to differentiate
18031801
the types of ordinary and UTF-8 literals\iref{lex.string}.
1804-
\effect
1805-
Valid ISO \CppXVII{} code using \tcode{concept}, \tcode{requires},
1806-
or \tcode{char8_t} as an identifier is not valid in this International Standard.
1802+
\item
1803+
The \tcode{concept} keyword is
1804+
added to enable the definition of concepts\iref{temp.concept}.
1805+
\item
1806+
The \tcode{consteval} keyword is added to
1807+
declare immediate functions\iref{dcl.constexpr}.
1808+
\item
1809+
The \tcode{requires} keyword is added
1810+
to introduce constraints through a \grammarterm{requires-clause} or
1811+
a \grammarterm{requires-expression}.
1812+
\end{itemize}
1813+
\effectafteritemize
1814+
Valid ISO \CppXVII{} code using
1815+
\tcode{char8_t},
1816+
\tcode{concept},
1817+
\tcode{consteval},
1818+
or \tcode{requires}
1819+
as an identifier is not valid in this International Standard.
18071820

18081821
\diffref{lex.operators}
18091822
\change New operator \tcode{<=>}.

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}%
@@ -736,17 +739,21 @@
736739
\indextext{specifier!\idxcode{constexpr}}
737740

738741
\pnum
739-
The \tcode{constexpr} specifier shall be applied only to the definition of
740-
a variable or variable template or
741-
the declaration of a
742-
function or function template.
743-
A function or static data member declared with the \tcode{constexpr}
744-
specifier is implicitly an inline function or variable\iref{dcl.inline}.
742+
The \tcode{constexpr} specifier shall be applied only to
743+
the definition of a variable or variable template or
744+
the declaration of a function or function template.
745+
The \tcode{consteval} specifier shall be applied only to
746+
the declaration of a function or function template.
747+
A function or static data member
748+
declared with the \tcode{constexpr} or \tcode{consteval} specifier
749+
is implicitly an inline function or variable\iref{dcl.inline}.
745750
If any declaration of a function or function template has
746-
a \tcode{constexpr} specifier,
747-
then all its declarations shall contain the \tcode{constexpr} specifier. \begin{note} An
748-
explicit specialization can differ from the template declaration with respect to the
749-
\tcode{constexpr} specifier. \end{note}
751+
a \tcode{constexpr} or \tcode{consteval} specifier,
752+
then all its declarations shall contain the same specifier.
753+
\begin{note}
754+
An explicit specialization can differ from the template declaration
755+
with respect to the \tcode{constexpr} or \tcode{consteval} specifier.
756+
\end{note}
750757
\begin{note}
751758
Function parameters cannot be declared \tcode{constexpr}.\end{note}
752759
\begin{example}
@@ -776,12 +783,17 @@
776783
\end{example}
777784

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

786798
\pnum
787799
\indextext{specifier!\idxcode{constexpr}!function}
@@ -946,8 +958,9 @@
946958
\end{itemize}
947959

948960
\pnum
949-
The \tcode{constexpr} specifier has no
950-
effect on the type of a constexpr function or a constexpr constructor. \begin{example}
961+
The \tcode{constexpr} and \tcode{consteval} specifiers have no
962+
effect on the type of a constexpr function or a constexpr constructor.
963+
\begin{example}
951964
\begin{codeblock}
952965
constexpr int bar(int x, int y) // OK
953966
{ 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.
@@ -5880,9 +5894,9 @@
58805894

58815895
\pnum
58825896
An explicitly-defaulted function that is not defined as deleted may be declared
5883-
\tcode{constexpr} only if it would have been implicitly declared as
5884-
\tcode{constexpr}. If
5885-
a function is explicitly defaulted on its first declaration,
5897+
\tcode{constexpr} or \tcode{consteval} only
5898+
if it would have been implicitly declared as \tcode{constexpr}.
5899+
If a function is explicitly defaulted on its first declaration,
58865900
it is implicitly considered to be \tcode{constexpr} if the implicit
58875901
declaration would be.
58885902

source/expressions.tex

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,12 @@
12661266
\end{example}
12671267
\end{itemize}
12681268

1269+
\pnum
1270+
An \grammarterm{id-expression}
1271+
that denotes an immediate function\iref{dcl.constexpr}
1272+
shall appear as a subexpression of an immediate invocation or
1273+
in an immediate function context\iref{expr.const}.
1274+
12691275
\pnum
12701276
An \grammarterm{id-expression}
12711277
that denotes the specialization of a concept\iref{temp.concept}
@@ -1554,7 +1560,7 @@
15541560
\pnum
15551561
In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator},
15561562
each \grammarterm{decl-specifier}
1557-
shall either be \tcode{mutable} or \tcode{constexpr}.
1563+
shall be one of \tcode{mutable}, \tcode{constexpr}, or \tcode{consteval}.
15581564
\begin{note}
15591565
The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}.
15601566
\end{note}
@@ -1680,8 +1686,12 @@
16801686
The function call operator or any given operator template specialization
16811687
is a constexpr function if either
16821688
the corresponding \grammarterm{lambda-expression}{'s}
1683-
\grammarterm{parameter-declaration-clause} is followed by \tcode{constexpr}, or
1689+
\grammarterm{parameter-declaration-clause}
1690+
is followed by \tcode{constexpr} or \tcode{consteval}, or
16841691
it satisfies the requirements for a constexpr function\iref{dcl.constexpr}.
1692+
It is an immediate function\iref{dcl.constexpr}
1693+
if the corresponding \grammarterm{lambda-expression}{'s}
1694+
\grammarterm{parameter-declaration-clause} is followed by \tcode{consteval}.
16851695
\begin{note} Names referenced in
16861696
the \grammarterm{lambda-declarator} are looked up in the context in which the
16871697
\grammarterm{lambda-expression} appears. \end{note}
@@ -1759,7 +1769,9 @@
17591769
is the address of a function \tcode{F} that, when invoked,
17601770
has the same effect as invoking the closure type's function call operator.
17611771
\tcode{F} is a constexpr function
1762-
if the function call operator is a constexpr function.
1772+
if the function call operator is a constexpr function
1773+
and is an immediate function
1774+
if the function call operator is an immediate function.
17631775
For a generic lambda with no \grammarterm{lambda-capture}, the closure type has a
17641776
conversion function template to
17651777
pointer to function. The conversion function template has the same invented
@@ -6807,8 +6819,12 @@
68076819
if the value is of pointer type, it contains
68086820
the address of an object with static storage duration,
68096821
the address past the end of such an object\iref{expr.add},
6810-
the address of a function,
6811-
or a null pointer value, and
6822+
the address of a non-immediate function,
6823+
or a null pointer value,
6824+
6825+
\item
6826+
if the value is of pointer-to-member-function type,
6827+
it does not designate an immediate function, and
68126828

68136829
\item
68146830
if the value is an object of class or array type,
@@ -6818,8 +6834,18 @@
68186834
\defnx{permitted result of a constant expression}{constant expression!permitted result of}
68196835
if it is an
68206836
object with static storage duration that is either not a temporary object or is
6821-
a temporary object whose value satisfies the above constraints, or it is a
6822-
function.
6837+
a temporary object whose value satisfies the above constraints, or
6838+
it is a non-immediate function.
6839+
\begin{example}
6840+
\begin{codeblock}
6841+
consteval int f() { return 42; }
6842+
consteval auto g() { return f; }
6843+
consteval int h(int (*p)() = g()) { return p(); }
6844+
constexpr int r = h(); // OK
6845+
constexpr auto e = g(); // ill-formed: a pointer to an immediate function is
6846+
// not a permitted result of a constant expression
6847+
\end{codeblock}
6848+
\end{example}
68236849

68246850
\pnum
68256851
\begin{note} Since this document
@@ -6840,15 +6866,31 @@
68406866
It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}.
68416867
\end{example} \end{note}%
68426868

6869+
\pnum
6870+
An expression or conversion is in an \defn{immediate function context}
6871+
if it is potentially evaluated and
6872+
its innermost non-block scope is
6873+
a function parameter scope of an immediate function.
6874+
An expression or conversion is an \defn{immediate invocation}
6875+
if it is an explicit or implicit invocation of an immediate function and
6876+
is not in an immediate function context.
6877+
An immediate invocation shall be a constant expression.
6878+
\begin{note}
6879+
An immediate invocation is evaluated even in an unevaluated operand.
6880+
\end{note}
6881+
68436882
\pnum
68446883
\indextext{expression!potentially constant evaluated}%
6845-
An expression is \defn{potentially constant evaluated}
6884+
An expression or conversion is \defn{potentially constant evaluated}
68466885
if it is:
68476886

68486887
\begin{itemize}
68496888
\item
68506889
a potentially-evaluated expression\iref{basic.def.odr},
68516890

6891+
\item
6892+
an immediate invocation,
6893+
68526894
\item
68536895
a \grammarterm{constraint-expression},
68546896
including one formed from the \grammarterm{constraint-logical-or-expression}
@@ -6886,4 +6928,21 @@
68866928
is of non-volatile const-qualified integral type or of reference type.
68876929
\end{itemize}
68886930

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

source/lex.tex

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,9 @@
687687
\tcode{class} \\
688688
\tcode{concept} \\
689689
\tcode{const} \\
690-
\tcode{constexpr} \\
690+
\tcode{consteval} \\
691691
\columnbreak
692+
\tcode{constexpr} \\
692693
\tcode{const_cast} \\
693694
\tcode{continue} \\
694695
\tcode{decltype} \\
@@ -704,8 +705,8 @@
704705
\tcode{extern} \\
705706
\tcode{false} \\
706707
\tcode{float} \\
707-
\tcode{for} \\
708708
\columnbreak
709+
\tcode{for} \\
709710
\tcode{friend} \\
710711
\tcode{goto} \\
711712
\tcode{if} \\
@@ -721,8 +722,8 @@
721722
\tcode{private} \\
722723
\tcode{protected} \\
723724
\tcode{public} \\
724-
\tcode{register} \\
725725
\columnbreak
726+
\tcode{register} \\
726727
\tcode{reinterpret_cast} \\
727728
\tcode{requires} \\
728729
\tcode{return} \\
@@ -738,8 +739,8 @@
738739
\tcode{this} \\
739740
\tcode{thread_local} \\
740741
\tcode{throw} \\
741-
\tcode{true} \\
742742
\columnbreak
743+
\tcode{true} \\
743744
\tcode{try} \\
744745
\tcode{typedef} \\
745746
\tcode{typeid} \\

source/macros.tex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,16 @@
335335
\newcommand{\range}[2]{\Range{[}{)}{#1}{#2}}
336336

337337
%% Change descriptions
338-
\newcommand{\diffdef}[1]{\hfill\break\textbf{#1:}\space}
338+
\newcommand{\diffhead}[1]{\textbf{#1:}\space}
339+
\newcommand{\diffdef}[1]{\hfill\break\diffhead{#1}}
339340
\newcommand{\diffref}[1]{\pnum\textbf{Affected subclause:} \ref{#1}}
340341
\newcommand{\diffrefs}[2]{\pnum\textbf{Affected subclauses:} \ref{#1}, \ref{#2}}
341342
% \nodiffref swallows a following \change and removes the preceding line break.
342-
\def\nodiffref\change{\pnum\textbf{Change:}\space}
343+
\def\nodiffref\change{\pnum\diffhead{Change}}
343344
\newcommand{\change}{\diffdef{Change}}
344345
\newcommand{\rationale}{\diffdef{Rationale}}
345346
\newcommand{\effect}{\diffdef{Effect on original feature}}
347+
\newcommand{\effectafteritemize}{\diffhead{Effect on original feature}}
346348
\newcommand{\difficulty}{\diffdef{Difficulty of converting}}
347349
\newcommand{\howwide}{\diffdef{How widely used}}
348350

source/templates.tex

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

61516151
\pnum
61526152
The syntax for explicit instantiation is:

0 commit comments

Comments
 (0)