Why does the C compiler allow silent casting from uint16_t to an enum type?

Viewed 124

I was under the impression that it was an error or at least a warning for an integer type to be passed into a function that requires an enum argument. But I tried it in Compiler Explorer with -Wall -Wextra -Werror and there are no warnings. What am I missing? Does the C standard allow this?

Perhaps more importantly to my immediate use, is there a compiler option for gcc or clang to warn for this? The intent of having an enum type as a formal argument is as a contract to restrict to valid enum values.

#include <stdint.h>

typedef enum {
    FLAG_A = 1,
    FLAG_B = 2,
    FLAG_C = 4
} FLAG;

uint16_t flags = 0;

void clearFlags(FLAG flag)
{
    flags &= ~flag;
}

void doit()
{
    clearFlags(flags);   // this should not be ok; flags is type uint16_t
}
2 Answers

Enumerated types are compatible with integer types, so it is valid to pass an integer to a function that expects an enum as an argument.

Section 6.7.2.2p4 of the C standard regarding Enumeration Specifiers states:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of
representing the values of all the members of the
enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.

The definition of compatible types is in section 6.2.7p1:

Two types have compatible type if their types are the same.

So this means that an enumerated type actually has the same type as one of the integer types.

It's legal (as already explained in other answers). The compiler may (but is not required to) warn:

A value is given to an object of an enumerated type other than by assignment of an enumeration constant that is a member of that type, or an enumeration object that has the same type, or the value of a function that returns the same enumerated type

— Annex I, Common warnings.

Related