Skip to content

P1073R3 Immediate functions #2461

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

Merged
merged 1 commit into from
Nov 25, 2018
Merged
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
2 changes: 2 additions & 0 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4845,6 +4845,8 @@
\item
a \grammarterm{constant-expression}\iref{expr.const},
\item
an immediate invocation\iref{expr.const},
\item
an \grammarterm{init-declarator}\iref{dcl.decl} or
a \grammarterm{mem-initializer}\iref{class.base.init},
including the constituent expressions of the initializer,
Expand Down
12 changes: 11 additions & 1 deletion source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3709,7 +3709,11 @@
\begin{note}
Virtual functions support dynamic binding and object-oriented
programming. \end{note} A class that declares or inherits a virtual function is
called a \defnadj{polymorphic}{class}.
called a \defnadj{polymorphic}{class}.\footnote{If
all virtual functions are immediate functions,
the class is still polymorphic even though
its internal representation might not otherwise require
any additions for that polymorphic behavior.}

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

\pnum
A \tcode{consteval} virtual function shall not override
a virtual function that is not \tcode{consteval}.
A \tcode{consteval} virtual function shall not be overridden by
a virtual function that is not \tcode{consteval}.

\pnum
If an overriding function specifies contract conditions\iref{dcl.attr.contract},
it shall specify the same list of contract conditions as
Expand Down
27 changes: 20 additions & 7 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1795,15 +1795,28 @@
\diffref{lex.key}
\change New keywords.
\rationale Required for new features.
The \tcode{requires} keyword is added
to introduce constraints through a \grammarterm{requires-clause} or
a \grammarterm{requires-expression}. The \tcode{concept} keyword is
added to enable the definition of concepts\iref{temp.concept}.
\begin{itemize}
\item
The \tcode{char8_t} keyword is added to differentiate
the types of ordinary and UTF-8 literals\iref{lex.string}.
\effect
Valid ISO \CppXVII{} code using \tcode{concept}, \tcode{requires},
or \tcode{char8_t} as an identifier is not valid in this International Standard.
\item
The \tcode{concept} keyword is
added to enable the definition of concepts\iref{temp.concept}.
\item
The \tcode{consteval} keyword is added to
declare immediate functions\iref{dcl.constexpr}.
\item
The \tcode{requires} keyword is added
to introduce constraints through a \grammarterm{requires-clause} or
a \grammarterm{requires-expression}.
\end{itemize}
\effectafteritemize
Valid ISO \CppXVII{} code using
\tcode{char8_t},
\tcode{concept},
\tcode{consteval},
or \tcode{requires}
as an identifier is not valid in this International Standard.

\diffref{lex.operators}
\change New operator \tcode{<=>}.
Expand Down
64 changes: 39 additions & 25 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@
\terminal{friend}\br
\terminal{typedef}\br
\terminal{constexpr}\br
\terminal{consteval}\br
\terminal{inline}
\end{bnf}

Expand All @@ -269,9 +270,11 @@
same type.

\pnum
Each \grammarterm{decl-specifier} shall appear at most once in a complete
\grammarterm{decl-specifier-seq}, except that
\tcode{long} may appear twice.
Each \grammarterm{decl-specifier}
shall appear at most once in a complete \grammarterm{decl-specifier-seq},
except that \tcode{long} may appear twice.
The \tcode{constexpr} and \tcode{consteval} \grammarterm{decl-specifier}{s}
shall not both appear in a \grammarterm{decl-specifier-seq}.

\pnum
\indextext{ambiguity!declaration type}%
Expand Down Expand Up @@ -736,17 +739,21 @@
\indextext{specifier!\idxcode{constexpr}}

\pnum
The \tcode{constexpr} specifier shall be applied only to the definition of
a variable or variable template or
the declaration of a
function or function template.
A function or static data member declared with the \tcode{constexpr}
specifier is implicitly an inline function or variable\iref{dcl.inline}.
The \tcode{constexpr} specifier shall be applied only to
the definition of a variable or variable template or
the declaration of a function or function template.
The \tcode{consteval} specifier shall be applied only to
the declaration of a function or function template.
A function or static data member
declared with the \tcode{constexpr} or \tcode{consteval} specifier
is implicitly an inline function or variable\iref{dcl.inline}.
If any declaration of a function or function template has
a \tcode{constexpr} specifier,
then all its declarations shall contain the \tcode{constexpr} specifier. \begin{note} An
explicit specialization can differ from the template declaration with respect to the
\tcode{constexpr} specifier. \end{note}
a \tcode{constexpr} or \tcode{consteval} specifier,
then all its declarations shall contain the same specifier.
\begin{note}
An explicit specialization can differ from the template declaration
with respect to the \tcode{constexpr} or \tcode{consteval} specifier.
\end{note}
\begin{note}
Function parameters cannot be declared \tcode{constexpr}.\end{note}
\begin{example}
Expand Down Expand Up @@ -776,12 +783,17 @@
\end{example}

\pnum
A \tcode{constexpr} specifier used in the declaration of a function that is not a
constructor declares that
function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. Similarly, a
\tcode{constexpr} specifier used in
a constructor declaration declares that constructor to be a
\defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}.
A \tcode{constexpr} or \tcode{consteval} specifier
used in the declaration of a function that is not a constructor
declares that function to be
a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}.
Similarly, a \tcode{constexpr} or \tcode{consteval} specifier used in
a constructor declaration declares that constructor to be
a \defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}.
A function or constructor declared with the \tcode{consteval} specifier
is called an \defn{immediate function}.
A destructor, an allocation function, or a deallocation function
shall not be declared with the \tcode{consteval} specifier.

\pnum
\indextext{specifier!\idxcode{constexpr}!function}
Expand Down Expand Up @@ -946,8 +958,9 @@
\end{itemize}

\pnum
The \tcode{constexpr} specifier has no
effect on the type of a constexpr function or a constexpr constructor. \begin{example}
The \tcode{constexpr} and \tcode{consteval} specifiers have no
effect on the type of a constexpr function or a constexpr constructor.
\begin{example}
\begin{codeblock}
constexpr int bar(int x, int y) // OK
{ return x + y + x*y; }
Expand Down Expand Up @@ -1430,7 +1443,8 @@
\end{note}

\pnum
If the operand of a \grammarterm{decltype-specifier} is a prvalue,
If the operand of a \grammarterm{decltype-specifier} is a prvalue
and is not a (possibly parenthesized) immediate invocation\iref{expr.const},
the temporary materialization conversion is not applied\iref{conv.rval}
and no result object is provided for the prvalue.
The type of the prvalue may be incomplete or an abstract class type.
Expand Down Expand Up @@ -5880,9 +5894,9 @@

\pnum
An explicitly-defaulted function that is not defined as deleted may be declared
\tcode{constexpr} only if it would have been implicitly declared as
\tcode{constexpr}. If
a function is explicitly defaulted on its first declaration,
\tcode{constexpr} or \tcode{consteval} only
if it would have been implicitly declared as \tcode{constexpr}.
If a function is explicitly defaulted on its first declaration,
it is implicitly considered to be \tcode{constexpr} if the implicit
declaration would be.

Expand Down
75 changes: 67 additions & 8 deletions source/expressions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,12 @@
\end{example}
\end{itemize}

\pnum
An \grammarterm{id-expression}
that denotes an immediate function\iref{dcl.constexpr}
shall appear as a subexpression of an immediate invocation or
in an immediate function context\iref{expr.const}.

\pnum
An \grammarterm{id-expression}
that denotes the specialization of a concept\iref{temp.concept}
Expand Down Expand Up @@ -1554,7 +1560,7 @@
\pnum
In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator},
each \grammarterm{decl-specifier}
shall either be \tcode{mutable} or \tcode{constexpr}.
shall be one of \tcode{mutable}, \tcode{constexpr}, or \tcode{consteval}.
\begin{note}
The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}.
\end{note}
Expand Down Expand Up @@ -1680,8 +1686,12 @@
The function call operator or any given operator template specialization
is a constexpr function if either
the corresponding \grammarterm{lambda-expression}{'s}
\grammarterm{parameter-declaration-clause} is followed by \tcode{constexpr}, or
\grammarterm{parameter-declaration-clause}
is followed by \tcode{constexpr} or \tcode{consteval}, or
it satisfies the requirements for a constexpr function\iref{dcl.constexpr}.
It is an immediate function\iref{dcl.constexpr}
if the corresponding \grammarterm{lambda-expression}{'s}
\grammarterm{parameter-declaration-clause} is followed by \tcode{consteval}.
\begin{note} Names referenced in
the \grammarterm{lambda-declarator} are looked up in the context in which the
\grammarterm{lambda-expression} appears. \end{note}
Expand Down Expand Up @@ -1759,7 +1769,9 @@
is the address of a function \tcode{F} that, when invoked,
has the same effect as invoking the closure type's function call operator.
\tcode{F} is a constexpr function
if the function call operator is a constexpr function.
if the function call operator is a constexpr function
and is an immediate function
if the function call operator is an immediate function.
For a generic lambda with no \grammarterm{lambda-capture}, the closure type has a
conversion function template to
pointer to function. The conversion function template has the same invented
Expand Down Expand Up @@ -6807,8 +6819,12 @@
if the value is of pointer type, it contains
the address of an object with static storage duration,
the address past the end of such an object\iref{expr.add},
the address of a function,
or a null pointer value, and
the address of a non-immediate function,
or a null pointer value,

\item
if the value is of pointer-to-member-function type,
it does not designate an immediate function, and

\item
if the value is an object of class or array type,
Expand All @@ -6818,8 +6834,18 @@
\defnx{permitted result of a constant expression}{constant expression!permitted result of}
if it is an
object with static storage duration that is either not a temporary object or is
a temporary object whose value satisfies the above constraints, or it is a
function.
a temporary object whose value satisfies the above constraints, or
it is a non-immediate function.
\begin{example}
\begin{codeblock}
consteval int f() { return 42; }
consteval auto g() { return f; }
consteval int h(int (*p)() = g()) { return p(); }
constexpr int r = h(); // OK
constexpr auto e = g(); // ill-formed: a pointer to an immediate function is
// not a permitted result of a constant expression
\end{codeblock}
\end{example}

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

\pnum
An expression or conversion is in an \defn{immediate function context}
if it is potentially evaluated and
its innermost non-block scope is
a function parameter scope of an immediate function.
An expression or conversion is an \defn{immediate invocation}
if it is an explicit or implicit invocation of an immediate function and
is not in an immediate function context.
An immediate invocation shall be a constant expression.
\begin{note}
An immediate invocation is evaluated even in an unevaluated operand.
\end{note}

\pnum
\indextext{expression!potentially constant evaluated}%
An expression is \defn{potentially constant evaluated}
An expression or conversion is \defn{potentially constant evaluated}
if it is:

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

\item
an immediate invocation,

\item
a \grammarterm{constraint-expression},
including one formed from the \grammarterm{constraint-logical-or-expression}
Expand Down Expand Up @@ -6886,4 +6928,21 @@
is of non-volatile const-qualified integral type or of reference type.
\end{itemize}

\begin{example}
\begin{codeblock}
struct N {
constexpr N() {}
N(N const&) = delete;
};
template<typename T> constexpr void bad_assert_copyable() { T t; T t2 = t; }
using ineffective = decltype(bad_assert_copyable<N>());
// \tcode{bad_assert_copyable<N>} is not needed for constant evaluation
// (and thus not instantiated)
template<typename T> consteval void assert_copyable() { T t; T t2 = t; }
using check = decltype(assert_copyable<N>());
// error: \tcode{assert_copyable<N>} is instantiated (because it is needed for constant
// evaluation), but the attempt to copy \tcode{t} is ill-formed
\end{codeblock}
\end{example}

\indextext{expression|)}
9 changes: 5 additions & 4 deletions source/lex.tex
Original file line number Diff line number Diff line change
Expand Up @@ -687,8 +687,9 @@
\tcode{class} \\
\tcode{concept} \\
\tcode{const} \\
\tcode{constexpr} \\
\tcode{consteval} \\
\columnbreak
\tcode{constexpr} \\
\tcode{const_cast} \\
\tcode{continue} \\
\tcode{decltype} \\
Expand All @@ -704,8 +705,8 @@
\tcode{extern} \\
\tcode{false} \\
\tcode{float} \\
\tcode{for} \\
\columnbreak
\tcode{for} \\
\tcode{friend} \\
\tcode{goto} \\
\tcode{if} \\
Expand All @@ -721,8 +722,8 @@
\tcode{private} \\
\tcode{protected} \\
\tcode{public} \\
\tcode{register} \\
\columnbreak
\tcode{register} \\
\tcode{reinterpret_cast} \\
\tcode{requires} \\
\tcode{return} \\
Expand All @@ -738,8 +739,8 @@
\tcode{this} \\
\tcode{thread_local} \\
\tcode{throw} \\
\tcode{true} \\
\columnbreak
\tcode{true} \\
\tcode{try} \\
\tcode{typedef} \\
\tcode{typeid} \\
Expand Down
6 changes: 4 additions & 2 deletions source/macros.tex
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,16 @@
\newcommand{\range}[2]{\Range{[}{)}{#1}{#2}}

%% Change descriptions
\newcommand{\diffdef}[1]{\hfill\break\textbf{#1:}\space}
\newcommand{\diffhead}[1]{\textbf{#1:}\space}
\newcommand{\diffdef}[1]{\hfill\break\diffhead{#1}}
\newcommand{\diffref}[1]{\pnum\textbf{Affected subclause:} \ref{#1}}
\newcommand{\diffrefs}[2]{\pnum\textbf{Affected subclauses:} \ref{#1}, \ref{#2}}
% \nodiffref swallows a following \change and removes the preceding line break.
\def\nodiffref\change{\pnum\textbf{Change:}\space}
\def\nodiffref\change{\pnum\diffhead{Change}}
\newcommand{\change}{\diffdef{Change}}
\newcommand{\rationale}{\diffdef{Rationale}}
\newcommand{\effect}{\diffdef{Effect on original feature}}
\newcommand{\effectafteritemize}{\diffhead{Effect on original feature}}
\newcommand{\difficulty}{\diffdef{Difficulty of converting}}
\newcommand{\howwide}{\diffdef{How widely used}}

Expand Down
2 changes: 1 addition & 1 deletion source/templates.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6146,7 +6146,7 @@
member function of a class template, or
variable template
shall not
use the \tcode{inline} or \tcode{constexpr} specifiers.
use the \tcode{inline}, \tcode{constexpr}, or \tcode{consteval} specifiers.

\pnum
The syntax for explicit instantiation is:
Expand Down