[cfe-dev] defaulted default constructor with initializer
Kal
b17c0de at gmail.com
Fri Apr 17 00:48:37 PDT 2015
Am 17.04.15 um 08:55 schrieb Richard Smith:
> On Thu, Apr 16, 2015 at 11:33 PM, Kal <b17c0de at gmail.com
> <mailto:b17c0de at gmail.com>> wrote:
>
> Am 17.04.15 um 01:48 schrieb Richard Smith:
>> On Thu, Apr 16, 2015 at 10:16 AM, Kal <b17c0de at gmail.com
>> <mailto:b17c0de at gmail.com>> wrote:
>>
>> Consider this code:
>>
>> class A {
>> public:
>> struct I {
>> int i = 0;
>> };
>> A(I i = {}) {}
>> };
>>
>> With clang 3.6 this doesn't compile:
>> 4 : error: cannot use defaulted default constructor of 'I'
>> within 'A' outside of member functions because 'i' has an
>> initializer
>>
>> But if I change the code to
>>
>> class A {
>> public:
>> struct I {
>> int i = 0;
>> I() {}
>> };
>> A(I i = {}) {}
>> };
>>
>> then the code compiles. Why is this so? Aren't these equivalent?
>>
>>
>> They're not equivalent. The implicit constructor for A::I also
>> has a deduced exception specification, and computing that
>> exception specification requires the initializer for 'A::i' to
>> have already been parsed.
> You mean initializer for 'A::I' to have already been parsed? But
> hasn't the entire class definition for A::I and its initializers
> already been parsed before A::A?
>
>
> The exception specification for I::I is needed when parsing the
> default argument for A::A(I). The C++ standard does not say which
> order the "when the class is complete" elements are parsed; Clang
> handles them in this order:
>
> 1) attributes (thread safety attributes in particular)
> 2) default arguments and exception specifications
> 3) default member initializers
> 4) function bodies
>
> You can swap some of these around (or handle the delayed parts in
> purely lexical order), but doing so just changes which set of programs
> you reject. We handle (3) after (2) because it's unusual for a default
> argument or exception specification to need a default constructor for
> the current class (or a nested class). The best way to write portable
> code is to ensure that nothing in (2) or (3) depends on anything in
> (2), (3), or (4).
Thanks for clarifying this. BTW how does the standard say the exception
specifier for defaulted constructors should be derived from the member
initializers?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150417/b23954ec/attachment.html>
More information about the cfe-dev
mailing list