简体   繁体   中英

Prevent “enumerated type mixed with another type” warnings for boolean values in Keil uVision

I'm migrating an application I was developing in CodeWarrior v5.2 to Keil uVision v5.25, which uses the ARM C compiler v5.06.

Throughout my code I've used bool to represent boolean values, which is defined in a types.h file in my project as:

typedef enum _bool 
{ 
  false = 0, 
  true = 1 
} bool;

When I try to compile my code, the compiler generates warnings about lines where I implicitly assign the outcome of comparisons to variables with this type:

src\c\drivers\motor.c(168): warning:  #188-D: enumerated type mixed with another type
    const bool motorStopped = timeSinceLastEvent > maxPulseWidth;
src\c\drivers\motor.c(169): warning:  #188-D: enumerated type mixed with another type
    const bool motorStalled = motorStopped && isMotorDriven();

I understand why these warnings are being generated. I'm aware that I can suppress these warnings by explicitly casting to bool , like:

const bool motorStopped = (bool)(timeSinceLastEvent > maxPulseWidth);

However, doing this for every boolean condition is pretty ugly. I was wondering if there's a way I can configure Keil uVision / the ARM compiler (or modify my code) to not generate warnings about bool , without outright disabling warnings about mixing enumerated types with other types.

These are the options I have available to configure the compiler:

It felt dirty, but I resolved this by modifying the types.h file that came with the SDK kit by making it include stdbool.h instead of defining its own bool type. Recompiling my project produced no warnings/errors in either the third-party code that used bool or my own code.

For good measure I tried modifying it in a way that should still let it work if it were compiled in a C89 project:

#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#endif

// ...

#if __STDC_VERSION__ < 199901L
typedef enum _bool 
{ 
  false = 0, 
  true = 1 
} bool;
#endif

First of all, these kind of definitions are not logically correct in C.

C defines false as zero and true as not zero, which of course includes 1 but not only that. It can be dangerous in many situations:

The expression if(GetValue() == true) only evaluates as true if the return value of the function is 1 . It is extremely dangerous, and may be the source of many difficult-to-discover errors.

bool can have any value as int is the type behind it.

Casting does not change anything:

#include <stdio.h>
#include <string.h>

typedef enum _bool 
{ 
  false = 0, 
  true = 1 
} bool;

int main(void) {

    bool x;

    x = 50;
    printf("%d\n", x);

    x = (bool)50;
    printf("%d\n", x);
}

https://ideone.com/nNHPLg

You will explicitly convert the int values to zeroes or ones. For example:

bool x = !!something;

bool x = something ? true : false;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM