https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165
--- Comment #14 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to andysem from comment #13) > (In reply to Jonathan Wakely from comment #10) > > > C(D = {}); > > > > This requires checking whether C::D is default constructible, but we are > > still in the body of C, so C is not complete, which means C::D is not > > complete, which means we don't know if C::D is default constructible. > > Does it? I thought the default arguments were only evaluated at the point > where they are actually used, i.e. in this case - when `C` constructor is > invoked with no arguments. It's surprising, I agree. Whether the default argument is valid determines whether this constructor is considered a default constructor, which determines whether the compiler needs to implicitly declare a separate default constructor I think that's why the default argument is needed earlier than you expect. > If this is how the standard specifies compiler behavior, I wonder if this > should be considered as a defect (DR). I closed this as a dup of PR 96645 which has a DR number right there in the title. Like I said, see there for more details. > There is nothing in > `std::numeric_limits<double>::max()` that depends on the definition of `C`, > so there is no reason to prevent it from compiling. Are you sure? What if C::std is declared? Then the initializer means something very different. Again, see PR 96645 for further discussion of when the initializer can be compiled (and a possible patch to do it differently).