Skip to content

Commit 934ef3e

Browse files
Dawn Perchikzygoloid
authored andcommitted
P0017R1 Extension to aggregate initialization
Editorially added punctuation, changed 'aggregate' to a definition, replaced additional 'member's with 'element's, fixed referenced clause in [diff.cpp14], removed hyphen from aggregate-initialization, corrected the text in [diff.cpp14] to more accurately describe the incompatibility with C++14.
1 parent 8bed954 commit 934ef3e

File tree

2 files changed

+101
-27
lines changed

2 files changed

+101
-27
lines changed

source/compatibility.tex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,28 @@
15151515
int x = f(g1, g2); // ill-formed; previously well-formed
15161516
\end{codeblock}
15171517

1518+
\ref{dcl.init.aggr}
1519+
\change Definition of an aggregate is extended
1520+
to apply to user-defined types with base classes.
1521+
\rationale To increase convenience of aggregate initialization.
1522+
\effect
1523+
Valid \CppXIV code may fail to compile or produce different results in this
1524+
International Standard; initialization from an empty initializer list will
1525+
perform aggregate initialization instead of invoking a default constructor
1526+
for the affected types:
1527+
\begin{codeblock}
1528+
struct derived;
1529+
struct base {
1530+
friend struct derived;
1531+
private:
1532+
base();
1533+
};
1534+
struct derived : base {};
1535+
1536+
derived d1{}; // Error. The code was well-formed before.
1537+
derived d2; // still OK
1538+
\end{codeblock}
1539+
15181540
\rSec2[diff.cpp14.depr]{Annex~\ref{depr}: compatibility features}
15191541

15201542
\change

source/declarators.tex

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2849,19 +2849,47 @@
28492849
\indextext{\idxcode{\{\}}!initializer list}
28502850

28512851
\pnum
2852-
An
2853-
\term{aggregate}
2854-
is an array or a class (Clause~\ref{class}) with no
2855-
user-provided constructors (\ref{class.ctor}),
2852+
An \defn{aggregate} is an array or a class (Clause~\ref{class}) with
2853+
\begin{itemize}
2854+
\item
2855+
no user-provided constructors~(\ref{class.ctor})
2856+
(including those inherited~(\ref{namespace.udecl}) from a base class),
2857+
\item
28562858
no private or protected non-static data members (Clause~\ref{class.access}),
2857-
no base classes (Clause~\ref{class.derived}),
2858-
and no virtual functions (\ref{class.virtual}).
2859+
\item
2860+
no virtual functions~(\ref{class.virtual}), and
2861+
\item
2862+
no virtual, private, or protected base classes~(\ref{class.mi}).
2863+
\end{itemize}
2864+
\enternote
2865+
Aggregate initialization does not allow accessing
2866+
protected and private base class' members or constructors.
2867+
\exitnote
2868+
2869+
\pnum
2870+
\indextext{aggregate!elements}%
2871+
The \term{elements} of an aggregate are:
2872+
\begin{itemize}
2873+
\item
2874+
for an array, the array elements in increasing subscript order, or
2875+
\item
2876+
for a class, the direct base classes in declaration order
2877+
followed by the direct members in declaration order.
2878+
\end{itemize}
28592879

28602880
\pnum
2861-
When an aggregate is initialized by an initializer list, as specified in~\ref{dcl.init.list}, the elements of the initializer list are taken as initializers
2862-
for the members of the aggregate,
2863-
in increasing subscript or member order.
2864-
Each member is copy-initialized from the corresponding \grammarterm{initializer-clause}. If the \grammarterm{initializer-clause} is an expression and a narrowing conversion~(\ref{dcl.init.list}) is required to convert the expression, the program is ill-formed. \enternote If an \grammarterm{initializer-clause} is itself an initializer list, the member is list-initialized, which will result in a recursive application of the rules in this section if the member is an aggregate. \exitnote
2881+
When an aggregate is initialized by an initializer list
2882+
as specified in~\ref{dcl.init.list},
2883+
the elements of the initializer list are taken as initializers
2884+
for the elements of the aggregate, in order.
2885+
Each element is copy-initialized
2886+
from the corresponding \grammarterm{initializer-clause}.
2887+
If the \grammarterm{initializer-clause} is an expression and
2888+
a narrowing conversion~(\ref{dcl.init.list}) is required
2889+
to convert the expression, the program is ill-formed.
2890+
\enternote If an \grammarterm{initializer-clause} is itself an initializer list,
2891+
the element is list-initialized, which will result in a recursive application
2892+
of the rules in this section if the element is an aggregate. \exitnote
28652893
\enterexample
28662894
\begin{codeblock}
28672895
struct A {
@@ -2872,14 +2900,38 @@
28722900
} b;
28732901
} a = { 1, { 2, 3 } };
28742902
\end{codeblock}
2875-
28762903
initializes
28772904
\tcode{a.x}
28782905
with 1,
28792906
\tcode{a.b.i}
28802907
with 2,
28812908
\tcode{a.b.j}
28822909
with 3.
2910+
2911+
\begin{codeblock}
2912+
struct base1 { int b1, b2 = 42; };
2913+
struct base2 {
2914+
B() {
2915+
b3 = 42;
2916+
}
2917+
int b3;
2918+
};
2919+
struct derived : base1, base2 {
2920+
int d;
2921+
};
2922+
2923+
derived d1{{1, 2}, {}, 4};
2924+
derived d2{{}, {}, 4};
2925+
\end{codeblock}
2926+
initializes
2927+
\tcode{d1.b1} with 1,
2928+
\tcode{d1.b2} with 2,
2929+
\tcode{d1.b3} with 42,
2930+
\tcode{d1.d} with 4, and
2931+
\tcode{d2.b1} with 0,
2932+
\tcode{d2.b2} with 42,
2933+
\tcode{d2.b3} with 42,
2934+
\tcode{d2.d} with 4.
28832935
\exitexample
28842936

28852937
\pnum
@@ -2955,7 +3007,7 @@
29553007

29563008
\pnum
29573009
If there are fewer \grammarterm{initializer-clause}{s} in the list than there
2958-
are members in the aggregate, then each member not explicitly initialized
3010+
are elements in the aggregate, then each element not explicitly initialized
29593011
shall be initialized from its default member initializer~(\ref{class.mem}) or,
29603012
if there is no default member initializer, from an empty
29613013
initializer list~(\ref{dcl.init.list}).
@@ -3004,12 +3056,12 @@
30043056
\exitexample
30053057

30063058
\pnum
3007-
If an aggregate class \tcode{C} contains a subaggregate member
3008-
\tcode{m} that has no members for purposes of aggregate initialization,
3009-
the \grammarterm{initializer-clause} for \tcode{m} shall not be
3059+
If an aggregate class \tcode{C} contains a subaggregate element
3060+
\tcode{e} that has no elements for purposes of aggregate initialization,
3061+
the \grammarterm{initializer-clause} for \tcode{e} shall not be
30103062
omitted from an \grammarterm{initializer-list} for an object of type
30113063
\tcode{C} unless the \grammarterm{initializer-clause}{s} for all
3012-
members of \tcode{C} following \tcode{m} are also omitted.
3064+
elements of \tcode{C} following \tcode{e} are also omitted.
30133065
\enterexample
30143066

30153067
\begin{codeblock}
@@ -3084,20 +3136,20 @@
30843136
begins with a left brace,
30853137
then the succeeding comma-separated list of
30863138
\grammarterm{initializer-clause}{s}
3087-
initializes the members of a subaggregate;
3139+
initializes the elements of a subaggregate;
30883140
it is erroneous for there to be more
30893141
\grammarterm{initializer-clause}{s}
3090-
than members.
3142+
than elements.
30913143
If, however, the
30923144
\grammarterm{initializer-list}
30933145
for a subaggregate does not begin with a left brace,
30943146
then only enough
30953147
\grammarterm{initializer-clause}{s}
3096-
from the list are taken to initialize the members of the subaggregate;
3148+
from the list are taken to initialize the elements of the subaggregate;
30973149
any remaining
30983150
\grammarterm{initializer-clause}{s}
3099-
are left to initialize the next member of the aggregate
3100-
of which the current subaggregate is a member.
3151+
are left to initialize the next element of the aggregate
3152+
of which the current subaggregate is an element.
31013153
\enterexample
31023154

31033155
\begin{codeblock}
@@ -3156,16 +3208,16 @@
31563208

31573209
\pnum
31583210
All implicit type conversions (Clause~\ref{conv}) are considered when
3159-
initializing the aggregate member with an \grammarterm{assignment-expression}.
3211+
initializing the element with an \grammarterm{assignment-expression}.
31603212
If the
31613213
\grammarterm{assignment-expression}
3162-
can initialize a member, the member is initialized.
3163-
Otherwise, if the member is itself a subaggregate,
3214+
can initialize an element, the element is initialized.
3215+
Otherwise, if the element is itself a subaggregate,
31643216
brace elision is assumed and the
31653217
\grammarterm{assignment-expression}
3166-
is considered for the initialization of the first member of the subaggregate.
3218+
is considered for the initialization of the first element of the subaggregate.
31673219
\enternote As specified above, brace elision cannot apply to
3168-
subaggregates with no members for purposes of aggregate initialization; an
3220+
subaggregates with no elements for purposes of aggregate initialization; an
31693221
\grammarterm{initializer-clause} for the entire subobject is
31703222
required.\exitnote
31713223

@@ -3202,7 +3254,7 @@
32023254
\pnum
32033255
\indextext{initialization!array~of class~objects}%
32043256
\enternote
3205-
An aggregate array or an aggregate class may contain members of a
3257+
An aggregate array or an aggregate class may contain elements of a
32063258
class type with a user-provided constructor (\ref{class.ctor}).
32073259
Initialization of these aggregate objects is described in~\ref{class.expl.init}.
32083260
\exitnote

0 commit comments

Comments
 (0)