15

I have some code I'm porting to a new platform, and it started giving me an error about comparing two enumerators from two different enumerator-lists. I'm confused why it's giving me an error about this.

The enumeration specificers section of the C spec (6.7.2.2) states:

The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.127) An enumerator with = defines its enumeration constant as the value of the constant expression. If the first enumerator has no =, the value of its enumeration constant is 0.

So I should be able to use enum members the same as int constants. In this small sample program:

enum first {
  a,
  b
};

enum second {
 c,
 d
};

int main(){
    enum first myf = a;
    enum second mys = c;

    if(myf == mys)
        printf("same value\n"); 
    return 0;
}

When compiled with gcc -Wall -Werror I get the message:

error: comparison between ‘enum first’ and ‘enum second’ [-Werror=enum-compare]

I know that if I typecast both myf and mys as ints the compiler will be happy, just like I could set a couple of ints with the values from myf and mys and do the comparison; but why do I have to do either of these to get rid of the warning? Why does this warning exist in the first place? There must be some danger in doing this that I'm not seeing.


NOTE:
I have read the gcc documentation on this enum-compare flag, but it doesn't say much of anything:

-Wenum-compare
Warn about a comparison between values of different enumerated types. In C++ enumeral mismatches in conditional expressions are also diagnosed and the warning is enabled by default. In C this warning is enabled by -Wall.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • 2
    The gcc documentation is pretty explanatory. What's not clear there? – SomeWittyUsername Apr 02 '13 at 19:41
  • 2
    @icepack - *how* is that explanatory? It says what it does, it doesn't say word one about **why** anyone would need that. If the members of two different enums are both of type `int`, why do I need a warning when comparing one int to another int? – Mike Apr 02 '13 at 19:42
  • 1
    I think it's just warning you because it could easily be a mistake. The only other thing I can think of is that the enums can potentially be represented by different types. – teppic Apr 02 '13 at 19:43
  • 1
    @Mike key words are *enumeral mismatches* - this usually indicates a semantic error. See the below answers for elaboration – SomeWittyUsername Apr 02 '13 at 19:46
  • 2
    @Mike, if you define different `enum`s, it is presumably because they are arbitrary labels for _different_ things, e.g. `enum color {blue, yellow, green};` and `enum form {round, square, pentagonal};`. Then it doesn't make any sense to ask if your `color` is `pentagonal`... – vonbrand Apr 04 '13 at 20:36
  • You can't go about, and complain that you get errors when you activate `-Werror`... – v.oddou Sep 26 '19 at 09:29

4 Answers4

18

This isn't a warning because of a standards compliance issue, it's one of those "this doesn't seem right" kind of warnings. If you think of the typical uses of enums, doing such a comparison doesn't make much sense in many cases. For example:

enum Day {
  Sunday,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday
};

enum Month {
  January,
  February,
  March,
  April,
  May,
  June,
  July,
  August,
  September,
  October,
  November,
  December
};

enum Day day = Wednesday;
enum Month month = April; 

if (day == month) { ... }

This evaluates to true, but in general the comparison wouldn't make much sense. If you know you meant it, the typecast will convince the compiler, as you noted.

FatalError
  • 52,695
  • 14
  • 99
  • 116
  • Yeah, in general that makes sense...of course in *my* actual usecase it makes much more sense than days to months, but there’s no way for `gcc` to know that. ;) I don't suppose you're aware of a way to turn off `-Wenum-compare` when `-Wall` is on? – Mike Apr 02 '13 at 19:57
  • 1
    @Mike Try `-Wall -Wno-enum-compare` together. That should get you "all" warnings minus the enum compare warning. – FatalError Apr 02 '13 at 20:11
  • 7
    Bah, who still uses Sunday as the first day of the week? (+1, BTW) – Oliver Charlesworth Apr 02 '13 at 20:35
  • 1
    @OliCharlesworth, Yes the ISO standard mandates Monday, but Microsoft actually uses Sunday: http://msdn.microsoft.com/en-us/library/system.dayofweek(v=vs.110).aspx – Sebastian Jun 01 '14 at 07:09
3

if((int)myf == (int)mys)

That should do it. But it is dirty practice, only use it if both enums are different "versions" of the same group, like the newer one would contain new keywords at the end.

Zdenek
  • 690
  • 3
  • 14
  • 1
    nowadays one would use `if( static_cast(myf) == static_cast(mys) )` rather than implicit casting (see [this stackoverflow answer](https://stackoverflow.com/a/332086/2195180)) – Martin Feb 09 '21 at 07:37
  • @Martin You're referring to C++? – syockit Jan 27 '23 at 11:36
2

It's warning you because you have the warning flag on. The flag description doesn't explain why it exists, but it's probably safe to assume that it exists to prevent accidental comparisons between different enumeration types, because this usually is an error.

Furthermore, you are correct that you can use enumeration values the same as you can int constants. And if you said if (myf == c) then it most likely wouldn't have thrown a warning (I say most likely because I haven't experimented, and GCC honestly can do whatever it wants with that warning, but technically c is just an integral constant and does not carry the type enum second). But instead you're explicitly comparing two values of different enumeration types.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • 1
    `if you said if (myf == c) then it most likely wouldn't have thrown a warning` - an interesting theroy, I tried it out and it does still throw one (fyi). Ok, so since I need `-Wall -Werror` I'm stuck doing a typecast where one is essentially not needed. – Mike Apr 02 '13 at 19:55
  • 1
    @Mike - just compile with `-Wno-enum-compare`? – teppic Apr 02 '13 at 19:57
  • @Mike: Ok, so GCC is considering that a warn-able situation anyway. Not terribly surprising, as this warning is all about flagging something that's not technically illegal. – Lily Ballard Apr 02 '13 at 20:09
2

Its a warning but as you have compiled with -Wall -Werror all warnings are treated as error Rest you can find something in similar question.

Is there a correct way to avoid warnings when comparing two different enums?

with regards

hims

Community
  • 1
  • 1
hims15
  • 96
  • 1
  • 4
  • FYI, I did see that link when posting the question, but as the language was different, the question is technically different, and the answers don't make sense here; I disregarded it. Should have mentioned it in the question however. – Mike Apr 02 '13 at 19:59