On Tue, 26 Nov 2024 at 14:55, Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > > On Tue, 26 Nov 2024 at 14:07, Thomas Madlener <thomas.madlener@xxxxxxxxx> wrote: > >> > >> > // But this DOES > >> > if (!(a1 = a2)) return 1; > >> > >> > >> In this case, if the use of == was an accident and you had intended to > >> write !(a1 == a2) then the code would look the same (except for the > >> missing '=' character). The "extra" parentheses here would have to be > >> present because of the ! operator, so unlike the first case above, > >> they are not redundant. > > > > > > Thanks for the quick reply and explanation. That makes sense, and I didn't think about that. > > > >> The types involved (i.e. the fact that A::operator= is being called) > >> are not relevant at all, as far as I know. The warning operates purely > >> on the syntax and warns about the use of = where maybe == was > >> intended. > > > > > > OK. In that case the warning makes sense. I thought there was a bit more semantic analysis going on, but that would probably be rather hard to implement. > > > >> Using if ((!(a1 = a2))) suppresses the warning for this case. > > > > > > Thanks for the hint. I was for now going for if (auto assign = (a1 = a2); !assign) which works, but is quite a bit of additional noise compared to your solution. > > > > Given your explanations and the proposed fix, I am actually happy with just implementing that. But I am also curious why it doesn't happen with c++17. > > I'm thoroughly puzzled, but I'll follow up when I get an answer. The different behaviour with C++20 is because of the default comparisons feature in C++20, where operator!= can be synthesized from operator== as needed. The different rules for == and != in C++20 alter how G++ handles !(expr) and cause it to look into the expression, and then the warning code sees (a1 = a2) and triggers the warning. I don't think the difference was intended.