简体   繁体   中英

How to trigger integer conversion warning when passing enum instead of pointer

Given the following code

#include <stdio.h>

typedef enum{
    ISP_INPUT_NONE,
    ISP_INPUT_DOLBY
} UserStream_t;

int someFunc(const char * str) {
    printf("%s", str);
    return 0;
}

int main(int argc, char** arg)
{
    int a = ISP_INPUT_NONE;
    someFunc(ISP_INPUT_NONE);
    someFunc(a);
    return 0;
}

The second call triggers an integer conversion warning, but the first doesn't.

gcc -Wall test.c 
test.c: In function ‘main’:
test.c:17:14: warning: passing argument 1 of ‘someFunc’ makes pointer from integer without a cast [-Wint-conversion]
   17 |     someFunc(a);
      |              ^
      |              |
      |              int
test.c:8:27: note: expected ‘const char *’ but argument is of type ‘int’
    8 | int someFunc(const char * str) {
      |              ~~~~~~~~~~~~~^~~

Are enum silently converted to pointers? I thought C enums were considered as integers. I would like the first call to generate the same warning as the second.

Are enum silently converted to pointers?

Well, some of them. ISP_INPUT_NONE is 0 and enumeration values are constant expressions and a constant expression with the value 0 is a null pointer constant. And converting a null pointer constant to another pointer is just normal.

The warning will still be issued if the enum value is not 0 , for example for someFunc(ISP_INPUT_DOLBY); .

How to trigger integer conversion warning when passing enum instead of pointer

Ideas:

Start enum with 1 instead of 0.

typedef enum {
    ISP_INPUT_NONE = 1,
    ISP_INPUT_DOLBY
} UserStream_t;

Use a structure and have conversion errors.

typedef struct {
   unsigned char val;
} UserStream_t;
static const UserStream_t ISP_INPUT_NONE = {0};
static const UserStream_t ISP_INPUT_DOLBY = {1};

Some way use a macro so that ISP_INPUT_NONE is not a constant expression.

static int entity(int a) { return a; }

typedef enum{
    ISP_INPUT_NONE,
#define ISP_INPUT_NONE (entity(ISP_INPUT_NONE))
    ISP_INPUT_DOLBY
} UserStream_t;

Use clang compiler with -Wnon-literal-null-conversion option.

In g++ there is -Wzero-as-null-pointer-constant option, but no such option for C in gcc. You could also make a feature request to gcc.

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