<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 16, 2015 at 11:33 PM, Kal <span dir="ltr"><<a href="mailto:b17c0de@gmail.com" target="_blank">b17c0de@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    <div>Am 17.04.15 um 01:48 schrieb Richard
      Smith:<br>
    </div><div><div class="h5">
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">On Thu, Apr 16, 2015 at 10:16 AM, Kal
            <span dir="ltr"><<a href="mailto:b17c0de@gmail.com" target="_blank">b17c0de@gmail.com</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div bgcolor="#FFFFFF" text="#000000"> Consider this code:<br>
                <br>
                class A {<br>
                public:<br>
                  struct I {<br>
                    int i = 0;<br>
                  };<br>
                  A(I i = {}) {}<br>
                };<br>
                <br>
                With clang 3.6 this doesn't compile:<br>
                4 : error: cannot use defaulted default constructor of
                'I' within 'A' outside of member functions because 'i'
                has an initializer<br>
                <br>
                But if I change the code to<br>
                <br>
                class A {<br>
                public:<br>
                  struct I {<br>
                    int i = 0;<br>
                    I() {}<br>
                  };<br>
                  A(I i = {}) {}<br>
                };<br>
                <br>
                then the code compiles. Why is this so? Aren't these
                equivalent?</div>
            </blockquote>
            <div><br>
            </div>
            <div>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.</div>
          </div>
        </div>
      </div>
    </blockquote></div></div>
    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?<br>
  </div>

</blockquote></div><br></div><div class="gmail_extra">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:</div><div class="gmail_extra"><br></div><div class="gmail_extra"> 1) attributes (thread safety attributes in particular)</div><div class="gmail_extra"> 2) default arguments and exception specifications</div><div class="gmail_extra"> 3) default member initializers</div><div class="gmail_extra"> 4) function bodies</div><div class="gmail_extra"><br></div><div class="gmail_extra">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).</div></div>