https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113830
--- Comment #7 from Bo Wang <wangbopku15 at gmail dot com> --- (In reply to Jakub Jelinek from comment #5) > Probably we just don't instantiate g because nothing needs it. > With > template<typename T> void f() { > struct S { void g(int n = T::unknown){}; }; > S s; > s.g(); > } > template void f<int>(); > we error: > pr113830.C: In instantiation of ‘void f() [with T = int]’: > pr113830.C:6:22: required from here > 6 | template void f<int>(); > | ^ > pr113830.C:2:32: error: ‘unknown’ is not a member of ‘int’ > 2 | struct S { void g(int n = T::unknown){}; }; > | ^~~~~~~ > pr113830.C:4:6: note: when instantiating default argument for call to > ‘void f()::S::g(int) [with T = int]’ > 4 | s.g(); > | ~~~^~ > but when one uses s.g(0); instead of s.g(); we accept it as well. As mentioned in Comment 3, the following does not appear to be valid code, but it still compiles. This is unrelated to whether or not the argument is used. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template<typename T> void f() { struct S { void g(int n = T::unknown) noexcept(T::unknown); }; } template void f<int>(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~