gcc和C语句

时间:2016-04-23 23:54:58

标签: c gcc

我有一行代码如下:

if ((!s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))

和gcc给我说:

warning: suggest parentheses around operand of ‘!’ or change ‘&’ to ‘&&’ or ‘!’ to ‘~’ [-Wparentheses]

所以,我很好奇,因为它确实编译了,gcc在做什么?是不是整个第一段,还是只有s2->lines[i]->flags

换句话说,是gcc假设:

if (!(s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))

if (((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))

或者其他什么?

3 个答案:

答案 0 :(得分:4)

是的,gcc假设你的意思是

if (((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))

因为这就是语言的优先规则所说的。但由于这几乎肯定不是你想要的,gcc建议你写

if ((!(s2->lines[i]->flags & ML_TWOSIDED)) || (s2->lines[i]->backsector == s1))

代替。

答案 1 :(得分:3)

一元运算符的优先级始终高于二元运算符,这意味着GCC将表达式视为

((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1)

GCC对您使用逻辑子表达式(!运算符)作为按位表达式(&的操作数这一事实感到困惑运营商)。虽然这里没有任何违法行为(并且行为定义明确),但这仍然不是经常使用的东西。当按位和逻辑语义混合时,通常它在较低级别为按位而在较高级别为逻辑,而不是相反。

出于这个原因,GCC要求您通过一些额外的括号来确认您的意图。看来GCC的担忧是合理的:这确实不是你想写的。

答案 2 :(得分:2)

gcc正在做什么?根据一些观察到的含糊不清和非传统的运营商使用情况,仅建议采取行动:

您原来的陈述:

if ((!s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1))

海湾合作委员会警告:

警告:建议围绕'!'操作数括号或将'&'改为'&&'或'!'改为'〜'[-Whatarentheses]

~&是按位运算符
!||&&是逻辑运算符

警告表示您正在以非常规方式一起使用按位逻辑运算符。虽然是合法的,但它会以这种方式编译,GCC会问你是否打算这样做,并以三种选择的形式提供分析得出的建议:

1)警告:在'!'

的操作数周围建议括号
if ((!(s2->lines[i]->flags & ML_TWOSIDED)) || (s2->lines[i]->backsector == s1))
      ^                                 ^

2)或将'&'更改为'&&'

if ((!s2->lines[i]->flags && ML_TWOSIDED) || (s2->lines[i]->backsector == s1))
                          ^^

3)或'!'到'〜'

  if ((~s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1)) 
       ^     to match       ^

只有你知道意图是什么。我的猜测是1)&的组合。 2):

if ((!(s2->lines[i]->flags && ML_TWOSIDED)) || (s2->lines[i]->backsector == s1))
      ^                    ^^            ^