8

enum elements' names are susceptible to overlap/collide with both other enum elements names, variable names, etc...

enum Fruit
{
    apple,
    orange
};
typedef enum Fruit Fruit;


enum Color
{
    red,
    orange // <-- ERROR
};
typedef enum Color Color;


char apple='a'; // <-- ERROR

Is there a C99 compliant solution to avoid collision other than prefixing every enum element name?


Side note: this question has already an answer for C++

How to avoid name conflicts for two enum values with the same name in C++?

I'm looking for a C99 solution.

Community
  • 1
  • 1
Paolo
  • 14,386
  • 26
  • 64
  • 85
  • Yes, use an appropriate name like `color_orange` and `fruit_orange`. It should also avoid the confusion when reading. – Iharob Al Asimi Feb 13 '16 at 13:09
  • Is there a [...] solution **other than prefixing every enum element name** ? – Paolo Feb 13 '16 at 13:11
  • Maybe but it would likely be a bad solution, this is a good solution that helps readability too. – Iharob Al Asimi Feb 13 '16 at 13:11
  • is there anything better readable than `Fruit f = orange;` and `Color c = orange;` ? It's tidy and no doubt than `f` is a fruit and `c` a color – Paolo Feb 13 '16 at 13:16
  • 1
    Yes `Fruit fruit = FruitOrange;`. Oh and in this case `switch (fruit) {case FruitOrange: break ...}`. If there are many fruits you will be glad to prefix them. Also `f` can be for `file`, `f**ck`, and many other wrods that start with `f` `fruit` instead is simply `fruit`. – Iharob Al Asimi Feb 13 '16 at 13:16
  • that's ugly! :-) but of course if it's the only solution I'll go with that. "**There is no solution for that**" (if true) may be an appropriate answer. – Paolo Feb 13 '16 at 13:18
  • It's not ugly `Fuirt f = orange;` is ugly, why not make it `Fruit f = o;` too and shorten it more to make it prettier? – Iharob Al Asimi Feb 13 '16 at 13:19
  • I don't understand the question entirely. Do you want to refer to different entities with the same name? – jxh Feb 13 '16 at 17:56

1 Answers1

10

In C, there is no solution other than prefixing the names of the enum values.

As pointed out in the OP, C++ has a number of mechanisms, of which enum class is probably indicated for modern code. However, in practice the result is the same: you end up prefixing the name of the enum element with the name of the enum. Arguably, Fruit::orange is tidier than FruitOrange, but really it makes little difference to my eyes.

In some parallel universe, it would be great to have a language in which you could write:

Fruit selected = orange;

and have the compiler deduce the namespace of the constant on the right-hand side. But I don't see how that language could be C. C doesn't have namespaces in that sense, and even if it did, the type system only allows conversions; you cannot condition the syntax of the RHS of an operator based on the LHS (and I use the word syntax deliberately, because name lookup is a syntactic property in C).

Even if you did have some language hack which sometimes implictly inserted an enum namespace, you would still need the explicit prefix on any comparison, because

if (apple > orange)

does not have a context in which deduction could take place, even though the fact that enum values in C are all of type int does make FruitApple and FruitOrange comparable.

rici
  • 219,119
  • 25
  • 219
  • 314