1

I have a following simple code:

#include <stdint.h>
#include <stdbool.h>

static uint8_t getStatus(void) 
{
    return 123u;
}

bool getError(void)
{

    bool error =  (bool)getStatus();
    return error;
}

And I get a following warning from gcc:

error: cast from function call of type 'uint8_t {aka unsigned char}' to non-matching type '_Bool' [-Werror=bad-function-cast]

From gcc manual:

-Wbad-function-cast (C and Objective-C only) Warn whenever a function call is cast to a non-matching type. For example, warn if int malloc() is cast to anything *

So there are 3 interesting situation. Only 2 of them all allowed by gcc, but I don't see any potential difference between them.

bool error =  getStatus(); //THIS IS OK
return error;


bool error = (bool)getStatus(); //THIS IS BAD
return error;


bool error =  (bool)(uint8_t)getStatus(); //THIS IS OK!
return error;

So I have 3 questions:

  1. Why I can't cast a result from getStatus() to bool.
  2. Why I need to explicity cast result from getStatus to uint8_t and after that I can cast to bool.
  3. How the Werror=bad-function-cast flag can help me to find (or avoid) an issue, and which kind of issue?
PanPaskuda
  • 21
  • 3

1 Answers1

2

One reason for the behaviour is given in the excerpt that you provided: in C89 (but not in C99, C11, C17), it is acceptable to call a function without providing an explicit declaration. Then for example if you did not #include <stdlib.h>, then it is implicitly considered having the declaration int malloc(). And if you then use the bad habit of casting the return value of malloc:

char *foo = (char*)malloc(42);

then you've masked a grave error. Unfortunately char *foo = (char*)malloc(42); would even then compile fine, whereas char *foo = malloc(42); would cause a diagnostic message be printed.

The rule of thumb is to never cast the return value of a function call.

Note that the conversion to _Bool from uint8_t does not need a cast (an explicit conversion), it can be done with an implicit (castless) conversion, hence the existence of any cast would be at least a stylistic mistake.