llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.02k stars 11.96k forks source link

Undefined reference to defaulted equality-comparison operator of struct with anonymous nested struct #64300

Open burnpanck opened 1 year ago

burnpanck commented 1 year ago

Under Clang, the following struct is comparable at compile-time, but fails to link due to a missing symbol for the comparison operator (undefined reference to 'A::operator==(A const&) const')

struct A {
  bool operator==(const A&rhs) const = default;

  bool a  = false;
  struct {
    bool b  = false;
  };
};

See https://godbolt.org/z/r6sfoqaET

This is probably related to the fact that it difficult to spell a comparison operator for the nested struct, as the type of the rhs argument has no name. I'm not sure what the standard says about autogenerating comparison operators for nested structs in general, or the anonymous case specifically. GCC decides to delete A::operator==(const A&) const due to a missing comparison operator for the anonymous nested struct. ~[EDIT: Irrelevant] Both clang and GCC agree to provide a comparison operator for A if the nested struct is named, even if no operator== for that nested struct is explicitly declared.~

In any case, I believe a link failure is the least desired behaviour, especially because the linker error message is somewhat misleading in that it directs the attention to the outer struct instead of the nested struct.

EDIT: Obviously, naming that nested struct changes the meaning of the program significantly, as A then doesn't get an A.b member at all.

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-codegen