Is copy-initialization of an aggregate member associated with the corresponding initializer-clause?

38 views
Skip to first unread message

Edward Catmur

unread,
Feb 23, 2015, 2:30:59 PM2/23/15
to std-dis...@isocpp.org
From http://stackoverflow.com/q/21294831/567292:

struct S { int i; int j; };
int f() { S s{5, s.i}; return s.j; }

Is this defined behavior?

[dcl.init.aggr]/2 has:
When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list
are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each
member is copy-initialized from the corresponding initializer-clause.

[dcl.init.list]/4 has:
Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack
expansions (14.5.3), are evaluated in the order in which they appear. That is, every value computation and
side effect associated with a given initializer-clause is sequenced before every value computation and side
effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list.

The copy-initialization of an aggregate member is certainly a side effect, but is it "associated with" the corresponding initializer-clause or is that only intended to cover side-effects like in S s{++i, ++i}?

The alternative would be that the copy-initialization of aggregate members is associated with the full-expression; this could e.g. be more efficient where it is possible to initialize multiple aggregate members en bloc.

Johannes Schaub

unread,
Feb 27, 2015, 4:01:15 PM2/27/15
to std-dis...@isocpp.org
2015-02-23 19:30 GMT+00:00 Edward Catmur <e...@catmur.co.uk>:
> From http://stackoverflow.com/q/21294831/567292:
>
> struct S { int i; int j; };
> int f() { S s{5, s.i}; return s.j; }
>
> Is this defined behavior?
>
> [dcl.init.aggr]/2 has:
>>
>> When an aggregate is initialized by an initializer list, as specified in
>> 8.5.4, the elements of the initializer list
>> are taken as initializers for the members of the aggregate, in increasing
>> subscript or member order. Each
>> member is copy-initialized from the corresponding initializer-clause.
>
>
> [dcl.init.list]/4 has:
>>
>> Within the initializer-list of a braced-init-list, the
>> initializer-clauses, including any that result from pack
>> expansions (14.5.3), are evaluated in the order in which they appear. That
>> is, every value computation and
>> side effect associated with a given initializer-clause is sequenced before
>> every value computation and side
>> effect associated with any initializer-clause that follows it in the
>> comma-separated list of the initializer-list.
>
>
> The copy-initialization of an aggregate member is certainly a side effect,
> but is it "associated with" the corresponding initializer-clause or is that
> only intended to cover side-effects like in S s{++i, ++i}?
>

This seems to be a variant of
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343 . My
example was

struct A {
bool &b;
A(bool &b):b(b) { }
~A() { std::cout << b; }
bool yield() { return true; }
};

bool b = A(b).yield();
int main() { }

And the issue seemed whether the initialization of "b" belongs to any
expression at all, or whether it is a "ghost effect" independent of
the initializing full-expression. In your case, the situation appears
to be similar.
Reply all
Reply to author
Forward
0 new messages