简体   繁体   中英

Is there a warning for assigning an enum variable with a value out of the range of the enum?

I have a C function which uses an enum as parameter, like the example bellow:

typedef enum
{
  AB, 
  CD
} A;

void f(A input)
{
  // do something
}

int main(void)
{
   // do something
   f(-10);
   // do something
}

Is there a warning that I can enable for assigning an enum variable with a value out of the range of the enum?

There is an open bug for it in the GCC bug database. It seems that GCC does not contain such a feature yet. There is an option called -Wc++-compat which would complain - among myriad other things, about any integer being converted implicitly to an enum type.

A related feature has just landed into the GCC repository. In GCC trunk (but not in 9.2.1 which is the compiler of Ubuntu 19.10), there is a switch -Wenum-conversion , which would warn about the use of an unrelated enum value, but not a bare integer; ie with the code below it will warn about the latter function call, but not the former. :

typedef enum{ AB, CD } A;

typedef enum{ EF, GH } B;

void f(A input){
    (void)input;
}

int main(void){
    f(-10);
    f(GH);
}

The diagnostics from compiling with -Wenum-conversion would be

<source>: In function 'main':
<source>:18:6: warning: implicit conversion from 'enum <anonymous>' to 'A' [-Wenum-conversion]
   18 |    f(GH);
      |      ^~

Even if enum is a user defined type, it is translated by the compiler as a primitive, in my case int , you can check it using:

#include <stdio.h>

#define printHelloIfEnumIsInt(x) \
    _Generic(x, int: puts("Hello"));

typedef enum {
  AB, 
  CD
} A;

int main(void)
{
    printHelloIfEnumIsInt(AB);
    return 0;
}

returns:

Hello

so any value in the range of INT_MIN ... INT_MAX is allowed.

I don't think there's any good way of doing it. But, provided that you do not use any = in your enum like enum foo {a=0, b=4} , you can do like this:

typedef enum{
  AB, 
  CD,
  A_max // Extra field that should be last
} A;

void f(A input){
    assert(input >= 0 && input < A_max);
    //  Do something
}

This works, because if no = is used, the first element will be zero, and all the following will add 1 for each of them.

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