Reputation: 67
I have a line of code that looks like this:
if ((!s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
and gcc gives me saying:
warning: suggest parentheses around operand of ‘!’ or change ‘&’ to ‘&&’ or ‘!’ to ‘~’ [-Wparentheses]
So, I'm curious as since it does compile, what is gcc doing? Is it not-ing the entire first segment, or only s2->lines[i]->flags
?
In other words, is gcc assuming:
if (!(s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
or
if (((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
or perhaps something else?
Upvotes: 1
Views: 464
Reputation: 23236
what is gcc doing? It is only suggesting a course of action based on some observed ambiguities and unconventional operator usage:
Your original statement:
if ((!s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
The GCC warning:
warning: suggest parentheses around operand of ‘!’ or change ‘&’ to ‘&&’ or ‘!’ to ‘~’ [-Wparentheses]
~
and &
are bitwise operators
!
, ||
and &&
are logical operators
The warning is recognizing that you are using a bitwise and logical operator together in a way that is unconventional. Although legal, and it will compile this way, GCC is asking if you meant to do that, and offering suggestions resulting from its analysis in the form of three options:
1) warning: suggest parentheses around operand of ‘!’
if ((!(s2->lines[i]->flags & ML_TWOSIDED)) || (s2->lines[i]->backsector == s1))
^ ^
2) or change ‘&’ to ‘&&’
if ((!s2->lines[i]->flags && ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
^^
3) or ‘!’ to ‘~’
if ((~s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
^ to match ^
Only you know what was intended. My guess is a combination of 1) & 2):
if ((!(s2->lines[i]->flags && ML_TWOSIDED)) || (s2->lines[i]->backsector == s1))
^ ^^ ^
Upvotes: 2
Reputation: 320747
Unary operators always have higher precedence than binary ones, meaning that GCC sees your expression as
((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1)
And GCC is puzzled by the fact that you used a logical subexpression (!
operator) as an operand of bitwise expression (&
operator). While there's nothing illegal in this (and the behavior is well defined), this is still not something that is used very often. When bitwise and logical semantics is mixed, usually it is bitwise at lower level and logical at higher level, not the other way around.
For this reason GCC asks you to confirm your intent with some extra parenthesis. And it appears that GCC's concern is justified: this is indeed not what you wanted to write.
Upvotes: 3
Reputation: 48052
Yes, gcc is assuming you meant
if (((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
since that's what the precedence rules of the language say. But since that's almost certainly not what you want, gcc is suggesting that you write
if ((!(s2->lines[i]->flags & ML_TWOSIDED)) || (s2->lines[i]->backsector == s1))
instead.
Upvotes: 4