https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115699
Bug ID: 115699 Summary: Anonymous structs should compare member-wise with C++20 defaulted operator== Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mital at mitalashok dot co.uk Target Milestone: --- Consider: ``` struct A { struct { int i; }; friend bool operator==(A, A) = default; }; static_assert(A{} == A{}); ``` This currently fails as the operator== is marked as deleted since it tries to compare the anonymous struct members as a whole: ``` <source>:7:24: error: use of deleted function 'constexpr bool operator==(A, A)' 7 | static_assert(A{} == A{}); | ^ <source>:5:15: note: 'constexpr bool operator==(A, A)' is implicitly deleted because the default definition would be ill-formed: 5 | friend bool operator==(A, A) = default; | ^~~~~~~~ <source>:2:3: error: no match for 'operator==' (operand types are 'A::<unnamed struct>' and 'A::<unnamed struct>') 2 | struct { | ^~~~~~ <source>:5:15: note: candidate: 'constexpr bool operator==(A, A)' (deleted) 5 | friend bool operator==(A, A) = default; | ^~~~~~~~ <source>:5:26: note: no known conversion for argument 1 from 'A::<unnamed struct>' to 'A' 5 | friend bool operator==(A, A) = default; | ^ ``` This is a GCC/C11 extension so there is no "official" expected behaviour, but this is surprising. This also leads to overload resolution being done with the unnamed struct type: ``` struct X { struct { bool b; }; bool c; template<typename T> friend constexpr bool operator==(T& L, T& R) { // T is the type of the anonymous struct static_assert(sizeof(T) == sizeof(bool)); return L.b == R.b; } friend constexpr bool operator==(const X& L, const X& R) = default; }; static_assert(X{} == X{}); ``` Where it might make more sense for each member of the anonymous struct to be considered a member of the class the struct is declared in so when operator== compares member by member, it compares each member of the anonymous struct. (This also applies to defaulted operator<=>)