Hi, I've found that on gcc 11.2 (tested on windows 10, with msys2), and compiling with : g++ -std=c++20 -pedantic -Wall -Wextra -Werror=return-type -Wshadow=local -Wempty-body -fdiagnostics-color -s -Os program.cpp -o program_gpp.exe -LC:/programs/msys64/mingw64/lib (I have also tried adding -Wtautological-compare but with the same effect described below). if I have a code with a struct person that in operator== erroneously compares one of its members, of an object type, with itself as in the following example : // this is a struct for field members, here comparison is implemented correctly struct object_member { int a = 20; bool operator==(const m& rhs) const { return a == rhs.a; } }; // this struct has the error in the operator== struct person { bool operator==(const person& rhs) const { // comparing this instance member with itself! return age == age; // instead of age == rhs.age } object_member age; }; int main() { person p1, p2; if(p1 == p2) std::cout << "equal!\n"; } I don't get the tautological compare warning. The behavior seems to occur only with struct/class types (also with string and optional), but not with primitive numeric types (i.e. : if age is an int, I get normally the tautological-compare warning. It occurs also if the expression is in AND with other correct comparisons. The causing part seems to be an operator== involving an object member (struct, class) compared with itself. In case of a single member I get instead the warning "rhs parameter not used", but if I add to the struct and comparison another field (ex.: int a), comparing it correctly, no warning shows at all: (...) operator==(const person& rhs) { return a == rhs.a && age == age; } (...) int a = 0; object_member age; (...) Is this correct ? or should I get this important warning also if the member is an object ? Note : I see clang 11.0 does not issue the warning either. Thanks, Marco
in object_member the comparison operator signature is bool operator==(const object_member& rhs) const
This is "correct" in that each function is compiled in isolation, and within the body of the function you are comparing two different objects, this->a and rhs.a The fact that rhs and *this actually alias each other **in your specific example** is not visible when compiling that function (and is not always going to be true for other alls to the function). You'll get just the same for something like: bool f(int& i, int& j) { return i == j; } int i = 0; bool b = f(i, i);
The warning could be smarter and assume that operator== has the usual semantics, and therefore 'age == age' would warn, even though *in theory* the operator== could do something meaningful when called like that. But in practice, warning would be helpful a lot more often than anybody writes weird operator== definitions where 'age == age' is actually what the developer meant to write. 99.999% of operator== functions do what you expect, and so 'age == age' is probably a mistake and should warn. Related to that, it would be nice if calls to operator== functions also gave -Wunused-value warnings, like the built-in == for scalars. Again, 99.999% of operator== functions have no side effects and are only called for the result, so if it's unused, the compiler should warn.