7

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?

ensc
  • 6,704
  • 14
  • 22
  • Would lint catch these? Especially an updated tool such as PCLint? See for instance https://invisible-island.net/personal/lint-tools.html and see this about lint http://pubs.opengroup.org/onlinepubs/7908799/xcu/lint.html – Richard Chambers Mar 16 '19 at 15:33
  • Looks like there is an updated version, splint, https://stackoverflow.com/questions/6881269/how-do-i-download-and-install-lint – Richard Chambers Mar 16 '19 at 15:39
  • @RichardChambers thinks for the hint; but "splint" does not seem to understand C99+ at all and aborts when seeing variadic macros (e.g. `#define log_err(_fmt, ...)`). – ensc Mar 16 '19 at 15:57

2 Answers2

2

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.

machine_1
  • 4,266
  • 2
  • 21
  • 42
0___________
  • 60,014
  • 4
  • 34
  • 74
  • My code is some simplified variant of refactored code where functions previously returned a `bool` value and where converted to return richer values. The `return true` resp. `return false` was missed in the refactoring and stayed literally; I just want to detect them. – ensc Mar 16 '19 at 15:43
  • 1
    Just don't include stdbool.h (you don't need it), and you'll catch *all* the occurences. – wildplasser Mar 16 '19 at 15:47
  • @wildplasser or if stdbool.h is buried deeper, a temporary local redefinition to "break" `bool`, `true` and `false` could also help identify the places to change. (don't leave it like that, but...) – Alex Celeste Mar 16 '19 at 15:50
  • @wildplasser Not a good idea. In my experience, using `stdbool.h` can significantly increase code readability, simply because booleans are labeled as such. Of course, I would have preferred a definition like `((_Bool)0)`, but I've never run into the OP's problem (even though I'm making liberal use of `stdbool.h`). – cmaster - reinstate monica Mar 16 '19 at 16:12
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.