Reputation: 6984
Is there some way to detect the bad usage of bool
values in code like
#include <stdbool.h>
void *foo(void)
{
return false;
}
int bar(void)
{
return true;
}
Both functions are accepted by gcc
(8.3.1) and clang
(7.0.1) without any warnings
$ gcc -Wall -W -pedantic -c x.c
$ clang -Xclang -analyzer-checker=alpha --analyze -Wall -W -pedantic -c x.c
$ clang -Wall -W -pedantic -c x.c
$
Compiling as C++ code would detect the problem in foo()
but is not an option but rest of code is C, not C++.
Are there other (-W
) options or switches which would create diagnostics for these cases?
Upvotes: 8
Views: 723
Reputation: 25703
Choosing the C23 standard helps with this, as C23 has a specific boolean type, distinct from integers. Compiling your code with GCC 13 using -std=c23
gives:
warning: initialization of pointer of type 'void *' to null from a constant boolean expression [-Wbool-conversion]
However, the bool
to int
conversion still won't be flagged.
Upvotes: 1
Reputation: 67602
Make the example less trivial:
bool x;
void *foo(void)
{
return x;
}
int bar(void)
{
return x;
}
and it want compile at all.
usually true and false are just definitions and have value 1
and 0
From the stdbool.h header file
#ifndef _STDBOOL_H
#define _STDBOOL_H
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#else /* __cplusplus */
in your first example you just return zero and most compilers will not warn as they treat it as NULL. Try to return true
and you will get the warning.
Upvotes: 2
Reputation: 133939
C defines the <stdbool.h>
macros true
and false
as expanding to integer constant expressions of value 1
and 0
respectively. Since they're int
s and bool
(_Bool
) in itself is an integer type, any such usage is equally valid. Even the value of the boolean expressions in C is an int
and not a bool
, so there is not much help for you with the bar
function.
However, foo
is a different beast - if the return value were true
then it would be caught right away because 1
is not convertible to a pointer. false
, having the integer constant value 0
is a null-pointer constant and will be converted to null pointer. You could perhaps catch the incorrect use by replacing the #include <stdbool.h>
with something that does the inclusion but defines false
as say 0.0
which is a falsy value but not an integer constant expression.
Upvotes: 2