Lone Learner
Lone Learner

Reputation: 20698

What is the point of allowing an identifier for enum?

Why doesn't the compiler complain when I try to assign incorrect values to variable a of type enum answer?

#include <stdio.h>

int main()
{
    enum answer {NO, YES};
    enum gender {MALE, FEMALE};

    enum answer a = 5; /* Assign an invalid value. */
    printf("answer: %d\n", a);

    a = MALE; /* Assign a value of wrong type */
    printf("answer: %d\n", a);

    return 0;
}

Here is the output:

$ gcc -std=c99 -pedantic -Wall -Wextra enum.c 
$ ./a.out
answer: 5
answer: 0

If enum doesn't lead to type-checking, then what is the point of having the syntax as:

enum [identifier] {enumerator-list}

I used answer and gender as the identifier for my enum. What is the point of allowing this syntax?

I mean this code could be very well written as

enum {NO, YES};
enum {MALE, FEMALE};

What is the point of allowing this syntax?

enum answer {NO, YES};
enum gender {MALE, FEMALE};

Upvotes: 11

Views: 1688

Answers (3)

ouah
ouah

Reputation: 145899

Assuming:

enum answer {NO, YES};

enum gender {MALE, FEMALE};

with:

enum answer bla = YES; 
enum gender blop = MALE;
int bip = 0;

While not required by the C Standard, it allows the implementations to warn in the cases below:

bla = blop;

bip =  bla;

Note that enum types are arithmetic types and assignment between objects of different arithmetic types is always permitted but the implementation is still free to warn. As some mentioned the comments, the rules with enum types are different for C++.

EDIT: another example:

enum ans {
    YES,
    NO,
    MAYBE
};


enum ans a = /* initializer */;

switch (a)
{
    case YES:
        break;
    case NO:
        break;
}

With -Wall (that is -Wswitch), gcc is able to warn that:

tst.c:15:5: warning: enumeration value ‘MAYBE’ not handled in switch

If you had:

enum {
    YES,
    NO,
    MAYBE
};

int a = /* initializer */;

gcc would not be able to warn. So actually using the enum type instead of only the enum constant helps static analyzer tools.

Upvotes: 0

krammer
krammer

Reputation: 2668

C exposes enumeration values directly as integer while in C++ enum is a real type. Hence in C++ enum results in a type check while in C enum just represents constants of type int. Therefore integer and enum values can be intermixed in all the arithmetic operations.

Upvotes: 4

Michał G&#243;rny
Michał G&#243;rny

Reputation: 19283

Why doesn't the compiler complain when I try to assign incorrect values to variable a of type enum answer?

Because in C, an enum is practically equivalent to an int. It was standarized like it, and simply too many programs rely on that behavior for it to change.

In C++, they are distinct types and the compiler complains:

$ g++ -Wall -Wextra a.c
a.c: In function 'int main()':
a.c:8:24: error: invalid conversion from 'int' to 'main()::answer' [-fpermissive]
a.c:11:14: error: cannot convert 'main()::gender' to 'main()::answer' in assignment

What is the point of allowing this syntax?

My quick guess would be forward compatibility.

Upvotes: 7

Related Questions