ensc
ensc

Reputation: 6984

gcc: how to detect bad `bool` usage

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

Answers (3)

Szabolcs
Szabolcs

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

0___________
0___________

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

C defines the <stdbool.h> macros true and false as expanding to integer constant expressions of value 1 and 0 respectively. Since they're ints 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

Related Questions