Skip to content

Commit 7cb8947

Browse files
zygoloidStefanus Du Toit
authored andcommitted
N3652 Relaxing constraints on constexpr functions
Conflicts resolved as indicated by N3652.
1 parent 0b01601 commit 7cb8947

7 files changed

Lines changed: 183 additions & 192 deletions

File tree

source/basic.tex

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,6 +2506,10 @@
25062506
Variables with static storage duration~(\ref{basic.stc.static}) or thread storage
25072507
duration~(\ref{basic.stc.thread}) shall be zero-initialized~(\ref{dcl.init}) before
25082508
any other initialization takes place.
2509+
A \term{constant initializer} for an object \tcode{o} is an expression that is a
2510+
constant expression, except that it may also invoke \tcode{constexpr} constructors
2511+
for \tcode{o} and its subobjects even if those objects are of non-literal class
2512+
types \enternote such a class may have a non-trivial destructor \exitnote.
25092513

25102514
\indextext{initialization!constant}%
25112515
\term{Constant initialization} is performed:
@@ -2519,12 +2523,8 @@
25192523

25202524
\item
25212525
if an object with static or thread storage duration is initialized
2522-
by a constructor call, if the constructor is a \tcode{constexpr} constructor, if all constructor
2523-
arguments are constant expressions (including conversions), and if, after function
2524-
invocation substitution~(\ref{dcl.constexpr}), every constructor call and full-expression in
2525-
the \grammarterm{mem-initializer}{s}
2526-
and in the \grammarterm{brace-or-equal-initializer}{s} for non-static data members
2527-
is a constant expression;
2526+
by a constructor call, and if the initialization full-expression is a constant
2527+
initializer for the object;
25282528

25292529
\item
25302530
if an object with static or thread storage duration is not initialized by a constructor call
@@ -3549,16 +3549,14 @@
35493549
A type is a \defn{literal type} if it is:
35503550

35513551
\begin{itemize}
3552+
\item \tcode{void}; or
35523553
\item a scalar type; or
35533554
\item a reference type; or
35543555
\item an array of literal type other than an array of runtime bound; or
35553556
\item a class type (Clause~\ref{class}) that
35563557
has all of the following properties:
35573558
\begin{itemize}
35583559
\item it has a trivial destructor,
3559-
\item every constructor call and full-expression in the
3560-
\grammarterm{brace-or-equal-initializer}{s} for non-static data members
3561-
(if any) is a constant expression~(\ref{expr.const}),
35623560
\item it is an aggregate type~(\ref{dcl.init.aggr}) or has
35633561
at least one \tcode{constexpr} constructor or constructor template that is not a copy or move constructor, and
35643562
\item all of its non-static data members and base classes are

source/compatibility.tex

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,34 @@
12991299
}
13001300
\end{codeblock}
13011301

1302+
\rSec1[diff.cpp03]{\Cpp and ISO \CppXI}
1303+
1304+
\pnum
1305+
\indextext{summary!compatibility~with ISO \CppXI}%
1306+
This subclause lists the differences between \Cpp and
1307+
ISO \CppXI (ISO/IEC 14882:2011, \doccite{Programming Languages --- \Cpp}),
1308+
by the chapters of this document.
1309+
1310+
\rSec2[diff.cpp11.dcl.dcl]{Clause \ref{dcl.dcl}: declarations}
1311+
1312+
\ref{dcl.constexpr}
1313+
\change \tcode{constexpr} non-static member functions are not implicitly
1314+
\tcode{const} member functions.
1315+
\rationale Necessary to allow \tcode{constexpr} member functions to mutate
1316+
the object.
1317+
\effect
1318+
Valid \CppXI code may fail to compile in this International Standard.
1319+
For example, the following code is valid in \CppXI
1320+
but invalid in this International Standard because it declares the same member
1321+
function twice with different return types:
1322+
1323+
\begin{codeblock}
1324+
struct S {
1325+
constexpr const int &f();
1326+
int &f();
1327+
};
1328+
\end{codeblock}
1329+
13021330
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13031331
\rSec1[diff.library]{C standard library}
13041332
\indextext{library!C standard}%

source/declarations.tex

Lines changed: 44 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -752,21 +752,21 @@
752752
Function parameters cannot be declared \tcode{constexpr}.\exitnote
753753
\enterexample
754754
\begin{codeblock}
755-
constexpr int square(int x); // OK: declaration
755+
constexpr void square(int &x); // OK: declaration
756756
constexpr int bufsz = 1024; // OK: definition
757757
constexpr struct pixel { // error: \tcode{pixel} is a type
758758
int x;
759759
int y;
760760
constexpr pixel(int); // OK: declaration
761761
};
762762
constexpr pixel::pixel(int a)
763-
: x(square(a)), y(square(a)) // OK: definition
764-
{ }
763+
: x(a), y(x) // OK: definition
764+
{ square(x); }
765765
constexpr pixel small(2); // error: \tcode{square} not defined, so \tcode{small(2)}
766766
// not constant~(\ref{expr.const}) so \tcode{constexpr} not satisfied
767767

768-
constexpr int square(int x) { // OK: definition
769-
return x * x;
768+
constexpr void square(int &x) { // OK: definition
769+
x *= x;
770770
}
771771
constexpr pixel large(4); // OK: \tcode{square} defined
772772
int next(constexpr int x) { // error: not for parameters
@@ -806,16 +806,16 @@
806806
its \grammarterm{function-body} shall be
807807
\tcode{= delete}, \tcode{= default}, or
808808
a \grammarterm{compound-statement}
809-
that contains only
809+
that does not contain
810810

811811
\begin{itemize}
812-
\item null statements,
813-
\item \grammarterm{static_assert-declaration}{s}
814-
\item \tcode{typedef} declarations and \grammarterm{alias-declaration}{s} that
815-
do not define classes or enumerations,
816-
\item \grammarterm{using-declaration}{s},
817-
\item \grammarterm{using-directive}{s},
818-
\item and exactly one return statement.
812+
\item an \grammarterm{asm-definition},
813+
\item a \tcode{goto} statement,
814+
\item a \grammarterm{try-block}, or
815+
\item a definition of a variable
816+
of non-literal type or
817+
of static or thread storage duration or
818+
for which no initialization is performed.
819819
\end{itemize}
820820

821821
\end{itemize}
@@ -826,13 +826,22 @@
826826
{ return x * x; } // OK
827827
constexpr long long_max()
828828
{ return 2147483647; } // OK
829-
constexpr int abs(int x)
830-
{ return x < 0 ? -x : x; } // OK
831-
constexpr void f(int x) // error: return type is \tcode{void}
832-
{ /* ... */ }
829+
constexpr int abs(int x) {
830+
if (x < 0)
831+
x = -x;
832+
return x; // OK
833+
}
834+
constexpr int first(int n) {
835+
static int value = n; // error: variable has static storage duration
836+
return value;
837+
}
838+
constexpr int uninit() {
839+
int a; // error: variable is uninitialized
840+
return a;
841+
}
833842
constexpr int prev(int x)
834-
{ return --x; } // error: use of decrement
835-
constexpr int g(int x, int n) { // error: body not just ``return expr''
843+
{ return --x; } // OK
844+
constexpr int g(int x, int n) { // OK
836845
int r = 1;
837846
while (--n > 0) r *= x;
838847
return r;
@@ -862,16 +871,8 @@
862871
\begin{itemize}
863872
\item
864873
either its \grammarterm{function-body} shall be \tcode{= default}, or the \grammarterm{compound-statement} of its \grammarterm{function-body}
865-
shall contain only
866-
867-
\begin{itemize}
868-
\item null statements,
869-
\item \grammarterm{static_assert-declaration}{s}
870-
\item \tcode{typedef} declarations and \grammarterm{alias-declaration}{s} that
871-
do not define classes or enumerations,
872-
\item \grammarterm{using-declaration}{s},
873-
\item and \grammarterm{using-directive}{s};
874-
\end{itemize}
874+
shall satisfy the constraints for a \grammarterm{function-body} of a
875+
\tcode{constexpr} function;
875876

876877
\item
877878
every non-variant non-static data member and base class sub-object
@@ -884,79 +885,26 @@
884885

885886
\item
886887
every constructor involved in initializing non-static
887-
data members and base class sub-objects shall be a \tcode{constexpr} constructor;
888-
889-
\item
890-
every \grammarterm{assignment-expression} that is an \grammarterm{initializer-clause}
891-
appearing directly or indirectly within a \grammarterm{brace-or-equal-initializer}
892-
for a non-static data member that is not named by a \grammarterm{mem-initializer-id}
893-
shall be a constant expression.
888+
data members and base class sub-objects shall be a \tcode{constexpr} constructor.
894889
\end{itemize}
895890

896891
\enterexample
897892
\begin{codeblock}
898893
struct Length {
899894
explicit constexpr Length(int i = 0) : val(i) { }
900895
private:
901-
int val;
896+
int val;
902897
};
903898
\end{codeblock}
904899
\exitexample
905900

906901
\pnum
907-
\indexdefn{function invocation substitution}\term{Function invocation substitution}
908-
for a call of a \tcode{constexpr} function or
909-
of a \tcode{constexpr} constructor means:
910-
911-
\begin{itemize}
912-
913-
\item
914-
implicitly converting each argument to the corresponding parameter
915-
type as if by copy-initialization,\footnote{The resulting converted
916-
value will include an lvalue-to-rvalue conversion~(\ref{conv.lval}) if
917-
the corresponding copy-initialization requires one.}
918-
919-
\item
920-
substituting that converted expression for each use of the corresponding parameter in the
921-
\grammarterm{function-body},
922-
923-
\item
924-
in a member function, substituting for each use of
925-
\tcode{this}~(\ref{class.this}) a prvalue pointer whose value is the
926-
address of the object for which the member function is called, and
927-
928-
\item
929-
in a \tcode{constexpr} function, implicitly converting the resulting
930-
returned expression or \grammarterm{braced-init-list} to the
931-
return type of the function as if by copy-initialization.
932-
\end{itemize}
933-
934-
Such substitution does not change the
935-
meaning. \enterexample
936-
\begin{codeblock}
937-
constexpr int f(void *) { return 0; }
938-
constexpr int f(...) { return 1; }
939-
constexpr int g1() { return f(0); } // calls \tcode{f(void *)}
940-
constexpr int g2(int n) { return f(n); } // calls \tcode{f(...)} even for \tcode{n == 0}
941-
constexpr int g3(int n) { return f(n*0); } // calls \tcode{f(...)}
942-
943-
namespace N {
944-
constexpr int c = 5;
945-
constexpr int h() { return c; }
946-
}
947-
constexpr int c = 0;
948-
constexpr int g4() { return N::h(); } // value is \tcode{5}, \tcode{c} is not looked up again after the substitution
949-
\end{codeblock}
950-
\exitexample
951-
952-
For a non-template, non-defaulted \tcode{constexpr} function, if no function
953-
argument values exist such that the function
954-
invocation substitution would produce a constant expression~(\ref{expr.const}), the
955-
program is ill-formed; no diagnostic required. For a non-template,
956-
non-defaulted, non-inheriting \tcode{constexpr} constructor, if no
957-
argument values exist such that after function invocation substitution, every constructor
958-
call and full-expression in the \grammarterm{mem-initializer}{s} would be a constant
959-
expression (including conversions), the program is ill-formed; no diagnostic required.
902+
For a non-template, non-defaulted
903+
\tcode{constexpr} function or a non-template, non-defaulted, non-inheriting
904+
\tcode{constexpr} constructor, if no argument values exist such that
905+
an invocation of the function or constructor could be an evaluated subexpression of a core
906+
constant expression~(\ref{expr.const}), the program is ill-formed; no diagnostic
907+
required.
960908
\enterexample
961909
\begin{codeblock}
962910
constexpr int f(bool b)
@@ -998,21 +946,16 @@
998946
function can appear in a constant expression.
999947

1000948
\pnum
1001-
A \tcode{constexpr} specifier for a non-static member
1002-
function that is not a constructor declares that member function to be
1003-
\tcode{const}~(\ref{class.mfct.non-static}).
1004-
\enternote The \tcode{constexpr} specifier has no
1005-
other effect on the function type.\exitnote
1006-
The keyword \tcode{const} is ignored if it appears in the \grammarterm{cv-qualifier-seq}
1007-
of the function declarator of the declaration of such a member function.
949+
The \tcode{constexpr} specifier has no
950+
effect on the type of a \tcode{constexpr} function or a \tcode{constexpr} constructor.
1008951
The class of
1009-
which that function is a member shall be a literal
952+
which a \tcode{constexpr} function is a member shall be a literal
1010953
type~(\ref{basic.types}). \enterexample
1011954
\begin{codeblock}
1012955
class debug_flag {
1013956
public:
1014957
explicit debug_flag(bool);
1015-
constexpr bool is_on(); // error: \tcode{debug_flag} not
958+
constexpr bool is_on() const; // error: \tcode{debug_flag} not
1016959
// literal type
1017960
private:
1018961
bool flag;
@@ -1035,10 +978,9 @@
1035978
that call shall be a constant expression~(\ref{expr.const}).
1036979
Otherwise,
1037980
or if a \tcode{constexpr} specifier is used in a reference declaration,
1038-
every full-expression that appears in its initializer shall be a constant expression. Each
981+
every full-expression that appears in its initializer shall be a constant expression. \enternote Each
1039982
implicit conversion used in converting the initializer expressions and each constructor call
1040-
used for the initialization shall be one of those allowed in a constant
1041-
expression~(\ref{expr.const}).
983+
used for the initialization is part of such a full-expression. \exitnote
1042984
\enterexample
1043985
\begin{codeblock}
1044986
struct pixel {

0 commit comments

Comments
 (0)