gcc-WParenthesis警告b=1!a&;b但不是!a&;1.
考虑以下简短计划:gcc-WParenthesis警告b=1!a&;b但不是!a&;1.,c,gcc,C,Gcc,考虑以下简短计划: int main() { int a = 5, b = 1, c; c = !a & b; c = !a & 1; return c; } 有人知道为什么gcc会对b=1发出警告吗;c=!a&b但不适用于c=!a&1 $gcc-Wall test.c 测试c:在函数“main”中: test.c:3:9:警告:建议在“!”的操作数周围加括号或将“&”改为“&&”或“!”到“~”[-wParenthess] c=!a&b;
int main() {
int a = 5, b = 1, c;
c = !a & b;
c = !a & 1;
return c;
}
有人知道为什么gcc会对b=1发出警告吗;c=!a&b代码>但不适用于c=!a&1代码>
$gcc-Wall test.c
测试c:在函数“main”中:
test.c:3:9:警告:建议在“!”的操作数周围加括号或将“&”改为“&&”或“!”到“~”[-wParenthess]
c=!a&b;
我的gcc版本是8.3.1(我尝试了另一个版本,但同样的情况也发生了)
我经常对gcc的“聪明”感到惊讶。这个问题看起来很容易解决。那么,为什么还要对第一个警告呢 当逻辑运算符和位运算符位于同一表达式中时,此警告将起作用,因为您通常希望使用其中一个或另一个,但不能同时使用这两个运算符
在这种情况下,您没有看到警告的原因是:
c = !a & 1;
是因为1是布尔值,因此&
和&
在该表达式中具有相同的效果
如果常数不是1或0,则会触发警告。但gcc不应该知道b=1,并将其视为与下面的行相同吗?@hko它显然没有密切关注流量,而只是关注一行。对于类型为int
的变量,它不会尝试求出值,但它知道是否给它一个常量。好的,在这种情况下,gcc似乎不够聪明,无法理解b总是1。我甚至尝试了static const int b=1
,同样的警告也发生了。我会接受你的回答,除非有人能告诉我为什么b=1仍然应该有警告;c=!a&b代码>案例。!(a&1)
可能不同于(!a)&1
,但是,这不是警告的目的吗?我不知道这是否有很大帮助,但我在GCC 9.2.0中得到了相同的效果,即使在编译器选项中包含-O3
。我想知道,如果没有优化可能会有所不同-显然不是。