https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57632
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Resolution|INVALID |--- Ever confirmed|0 |1 Last reconfirmed| |2022-01-07 Status|RESOLVED |NEW --- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- I agree with comment 3 that the current diagnostic is poor: #include <new> void* operator new(std::size_t mem) throw(std::bad_alloc); void* operator new(std::size_t mem) throw(std::bad_alloc); g++ -std=c++11 -c new.cc -Wno-deprecated new.cc:3:7: error: declaration of ‘void* operator new(std::size_t) throw (std::bad_alloc)’ has a different exception specifier 3 | void* operator new(std::size_t mem) throw(std::bad_alloc); | ^~~~~~~~ new.cc:2:7: note: from previous declaration ‘void* operator new(std::size_t)’ 2 | void* operator new(std::size_t mem) throw(std::bad_alloc); | ^~~~~~~~ Why does it accept the incorrect exception specification on line 2, but then give an error for an identical one on line 3? Why do we refer to line 2 in the note and say it's different, when it's not? Paolo's explanation in comment 1 doesn't make the behaviour correct, it just explains why we behave like that. Either both redeclarations should be valid or neither should be valid. So I think either we should either: - accept both redeclarations (as Clang does), or - give a diagnostic (maybe a pedwarn) for the first redeclaration because it doesn't match the one in <new> (and the implicit one predefined by the compiler), and fix the diagnostic to refer to the previous declaration in <new> instead of the one on line 2.