Discussion:
[std-discussion] possibly contradictory specification in [dcl.init.aggr]
Tam S. B.
2017-02-09 17:13:22 UTC
Permalink
[dcl.init.aggr]p8 says:

If there are fewer initializer-clauses in the list than there are elements in the aggregate, then each element
not explicitly initialized shall be initialized from its default member initializer (9.2) or, if there is no default
member initializer, from an empty initializer list (8.6.4).

But p11 says:

If an incomplete or empty initializer-list leaves a member of reference type uninitialized, the program is
ill-formed.

According to p8, aggregate members are always initialized (from the initializer-clause, from the default member initializer, or from an empty initializer list). However, p11 seems to imply that a member of reference type may be left uninitialized. How can this be? When does p11 apply?

All compilers I test seem to agree that if a reference member is neither initialized from the initializer-clause, nor initialized from the default member initializer, then it is uninitialized, despite the standard saying that the member shall be initialized from an empty initializer list in this case.

Also, does [dcl.init.aggr]p8 contradicts with [dcl.init]p12 "If no initializer is specifed for an object, the object is default-initialized. "?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2017-02-09 20:23:22 UTC
Permalink
Post by Tam S. B.
If there are fewer initializer-clauses in the list than there are elements
in the aggregate, then each element
not explicitly initialized shall be initialized from its default member
initializer (9.2) or, if there is no default
member initializer, from an empty initializer list (8.6.4).
If an incomplete or empty initializer-list leaves a member of reference
type uninitialized, the program is
ill-formed.
According to p8, aggregate members are always initialized (from the
initializer-clause, from the default member initializer, or from an empty
initializer list). However, p11 seems to imply that a member of reference
type may be left uninitialized. How can this be? When does p11 apply?
All compilers I test seem to agree that if a reference member is neither
initialized from the initializer-clause, nor initialized from the default
member initializer, then it is uninitialized, despite the standard saying
that the member shall be initialized from an empty initializer list in this
case.
There is no contradiction between paragraphs 8 and 11 in [dcl.init.aggr].
Basically paragraph 11 complements paragraph 8, by saying that an aggregate
with a member of reference type, which is not initialized by an
*initializer-list* is ill-formed, and that means a member of reference type
in an aggregate *cannot* be left uninitialized, otherwise the code will not
compile.


Also, does [dcl.init.aggr]p8 contradicts with [dcl.init]p12 "If no
Post by Tam S. B.
initializer is specifed for an object, the object is default-initialized. "?
No, [dclinit.aggr]/8 and [dcl.init]/12 are not contradictory.
[dcl.init.aggr] is about the initialization of aggregates with an
*initializer-list*, that is, an initializer is provided for the
initialization of an aggregate object, and in this case, the initializer is
the so called *initializer-list*. [dcl.init]/12 simply says that if *no*
initializer is provided for an object, of the aggregate type, the object is
default-initialized. Note that an empty *initializer-list* for an aggregate
object will also result in default initialization, as long as the aggregate
doesn't contain a reference member.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2017-02-09 20:29:43 UTC
Permalink
Post by Belloc
No, [dclinit.aggr]/8 and [dcl.init]/12 are not contradictory.
[dcl.init.aggr] is about the initialization of aggregates with an
*initializer-list*, that is, an initializer is provided for the
initialization of an aggregate object, and in this case, the initializer is
the so called *initializer-list*. [dcl.init]/12 simply says that if *no*
initializer is provided for an object, of the aggregate type, the object is
default-initialized. Note that an empty *initializer-list* for an
aggregate object will also result in default initialization, as long as the
aggregate doesn't contain a reference member.
Please replace this last statement by the one below:

No, [dclinit.aggr]/8 and [dcl.init]/12 are not contradictory.
[dcl.init.aggr] is about the initialization of aggregates with an
*initializer-list*, that is, an initializer is provided for the
initialization of an aggregate object, and in this case, the initializer is
the so called *initializer-list*. [dcl.init]/12 simply says that if *no* initializer
is provided for an object, of *any* type, the object is
default-initialized. Note that an empty *initializer-list* for an aggregate
object will also result in default initialization, as long as the aggregate
doesn't contain a reference member.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Tam S. B.
2017-02-09 22:38:01 UTC
Permalink
Basically paragraph 11 complements paragraph 8, by saying that an aggregate with a member of reference type, which is not initialized by an initializer-list is ill-formed
So "uninitialized" in p11 means "not initialized by an initializer-list"? I'm not totally convinced.
Note that an empty initializer-list for an aggregate object will also result in default initialization, as long as the aggregate doesn't contain a reference member.
AFAIK this is not true. Consider

#include <initializer_list>
struct X {
X(std::initializer_list<int>) {}
};

struct Y {
X x;
Y() = delete;
} y = {};

The aggregate initialization of `y` does not result in any default initialization. If it did, that would be a compile error, because X has no default constructor, and Y's default constructor is deleted.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2017-02-10 11:25:21 UTC
Permalink
On Thursday, February 9, 2017 at 8:40:29 PM UTC-2, Tam S. B. wrote:

So "uninitialized" in p11 means "not initialized by an initializer-list"?
Post by Tam S. B.
I'm not totally convinced.
That's what the spec says and that's exactly what I meant. For instance,
the snippet below doesn't compile:

struct A{
int& ri;
};
A a{};
Post by Tam S. B.
AFAIK this is not true. Consider
#include <initializer_list>
struct X {
X(std::initializer_list<int>) {}
};
struct Y {
X x;
Y() = delete;
} y = {};
The aggregate initialization of `y` does not result in any default
initialization. If it did, that would be a compile error, because X has no
default constructor, and Y's default constructor is deleted.
I apologize for what I said earliert in relation to this. From
[dcl.init.aggr]/8 <http://eel.is/c++draft/dcl.init.aggr#8>, aggregate
initialization has nothing to do with default initialization when there are
fewer elements in the list than there are elements in the aggregate.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2017-02-10 11:51:22 UTC
Permalink
On Thursday, February 9, 2017 at 8:40:29 PM UTC-2, Tam S. B. wrote:

So "uninitialized" in p11 means "not initialized by an initializer-list"?
Post by Tam S. B.
I'm not totally convinced.
That's what the spec says and that's exactly what I meant. For instance,
the snippet below doesn't compile:

struct A{
int& r;
};
A a{};
Post by Tam S. B.
Note that an empty initializer-list for an aggregate object will also
result in default initialization, as long as the aggregate doesn't contain
a reference member.
AFAIK this is not true. Consider
#include <initializer_list>
struct X {
X(std::initializer_list<int>) {}
};
struct Y {
X x;
Y() = delete;
} y = {};
The aggregate initialization of `y` does not result in any default
initialization. If it did, that would be a compile error, because X has no
default constructor, and Y's default constructor is deleted.
I apologize for what I said above. I was wrong. From [dcl.init.aggr]/8
<http://eel.is/c++draft/dcl.init.aggr#8>, aggregate initialization has
nothing to do with default initialization when there are fewer elements in
the list than there are elements in the aggregate.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Jens Maurer
2017-02-09 22:48:23 UTC
Permalink
Post by Tam S. B.
If there are fewer initializer-clauses in the list than there are elements in the aggregate, then each element
not explicitly initialized shall be initialized from its default member initializer (9.2) or, if there is no default
member initializer, from an empty initializer list (8.6.4).
If an incomplete or empty initializer-list leaves a member of reference type uninitialized, the program is
ill-formed.
This is Core Issue 2272: Implicit initialization of aggregate members of reference type

Jens
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2017-02-10 08:58:35 UTC
Permalink
Post by Jens Maurer
This is Core Issue 2272: Implicit initialization of aggregate members of reference type
Couldn't find this issue in C++ Standard Core Language Active Issues,
Revision 96
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Loading...