-某些编译器中的 Wint-in-bool-context 警告问题

问题描述 投票:0回答:2

我收到警告:

警告:'<<' in boolean context, did you mean '<' ? [-Wint-in-bool-context]

对于类似于以下的代码:

int a=7, b=3;
int index = ((a << 1) || b) && 5;
c compiler-warnings
2个回答
1
投票

解释此类警告背后的理由:

C 确实按照 C99 获得了布尔类型

_Bool
/
bool
,但该语言的各种逻辑运算符的行为没有进行任何更改。那就是:

  • 相等运算符
    ==
    /
    !=
  • 关系运算符
    <
    <=
    >
    >=
  • 逻辑与
    &&
  • 逻辑或
    ||
  • 逻辑否定
    !

尽管 C 具有布尔类型,但所有这些运算符都返回类型

int
,其值
1
0
。与 C++ 不同的是,所有这些运算符实际上都返回类型
bool
和值
true
/
false
。这是 C 的一个已知缺陷。

然而,将此类表达式视为布尔值是常见的良好做法。像 MISRA C 这样的编码指南鼓励使用“本质上是布尔值”的虚构类型,这意味着任何可以被视为

_Bool
的表达式。这样做的原因是,它使代码更加自我记录,也使创建各种与拼写错误相关的错误变得更加困难。

例如,

if(str)
可能意味着检查
NULL
,或者可能意味着检查空终止,但糟糕的是我们忘记取消引用。与
if(*str)
相同。然而,如果我们只将逻辑运算符的结果传递给
if
,代码就会变得更加清晰,并且更难编写错误:
if(str != NULL)
只能意味着检查 NULL,而
if(*str != '\0')
只能意味着检查 null 终止。

在您的情况下,

||
运算符仅关心操作数是否为零或非零(“本质上是布尔值”)。如果
a
非零,则
a<<1
不会改变这一点。如果
a
为零,则
a<<1
也为零。由于结果被传递给逻辑运算符,“在布尔上下文中”,移位是毫无意义的 - 因此出现警告。但当然
a<<1
可能会在另一个上下文中采用各种其他值,例如
if(a<<1 & mask)

强烈怀疑您实际上是想写

a<1
是合理的。因为这会产生 0 或 1,其中
<
也是逻辑运算符,如
||


1
投票

我找到了解决方案。我们应该避免将整数与逻辑运算符一起使用(例如,

||
&&
)。使用带有按位运算符的整数(例如
<<
&
|
等)就可以了。

有时,由于低优先级警告过滤器,我们在编译器上运行时不会遇到此问题。在复杂且对警告敏感的编译器中,它会出现。

© www.soinside.com 2019 - 2024. All rights reserved.