shodanex
shodanex

Reputation: 15406

How to trigger an integer conversion warning when passing an enum instead of a 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.

Upvotes: 0

Views: 145

Answers (1)

KamilCuk
KamilCuk

Reputation: 140970

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.

Upvotes: 3

Related Questions