Reputation: 47
I am a getting warning:
warning: '<<' in boolean context, did you mean '<' ? [-Wint-in-bool-context]
for the code similar to the following:
int a=7, b=3;
int index = ((a << 1) || b) && 5;
Upvotes: 0
Views: 981
Reputation: 47
I got the solution. We should avoid integers using with logical operators (eg., ||
and &&
). Using integers with bitwise operators (e.g., <<
, &
, |
, etc.) is fine.
Sometimes we don't get this problem while running on compilers because of low priority warning filters. In complex and warning sensitive compilers it comes up.
Upvotes: 1
Reputation: 214495
To explain the rationale behind such warnings:
C did get a boolean type _Bool
/bool
as per C99, but no changes were done to the behavior of the various logical operators of the language. That is:
==
/!=
<
,<=
,>
,>=
&&
||
!
.Despite C having a boolean type, all of these operators return type int
with value 1
or 0
. Unlike C++ where all of these operators actually return type bool
with value true
/false
. This is a known flaw of C.
It's common good practice however to treat such expressions as if they were boolean. Coding guidelines like MISRA C encourage the use of a fictional type "essentially boolean", meaning any expression that could be treated as _Bool
. The reason for this is that it makes code more self-documenting and also makes it harder to create various typo-related bugs.
For example if(str)
could mean check for NULL
, or it could mean check for null termination but oops we forgot to dereference. Same thing with if(*str)
. Whereas if we only pass the result of a logical operator to if
, the code becomes much clearer and it becomes harders to write bugs: if(str != NULL)
could only mean check for NULL and if(*str != '\0')
could only mean check for null termination.
In your case, the ||
operator only cares if the operands are zero or non-zero ("essentially boolean"). In case a
is non-zero then a<<1
will not change that. In case a
is zero, then a<<1
is zero as well. Since the result is passed on to a logical operator, "in a boolean context", the shift is pointless - hence the warning. But of course a<<1
might take all kinds of other values in another context such as for example if(a<<1 & mask)
.
It would be reasonable to strongly suspect that you actually meant to write a<1
instead. Because that would yield either 0 or 1, where <
is also a logical operator like ||
.
Upvotes: 1