In both c and c++ enum could be defined with tag
enum e_smth {
smth_one,
smth_two,
smth_err
};
or without tag
enum {
smth_one,
smth_two,
smth_err
};
If it was defined with tag it makes sense in switch statements in both c and c++ :
e_smth some_var;
....//do some stuff with some_var
switch (some_var)
{
case smth_one:
break;
case smth_two:
break;
}
will produce -Wswitch warning if this will be compiled with gcc or g++.
It makes sense in functions declarations and variables initialization in c++ :
e_smth var;
var=99;
Will produce -fpermissive error if compiled with g++.
Both types with or without tag could be used as one file #define macro without parameters.
update
could be used as one file
#definemacro without parameters
meant : Instead of writing #define MAX 1000 in file and adding MAX to global use enum { MAX=1000 } just in file scope
And what about anonymous enums, I’ve found just one use cases:
definition like typedef enum { a,b,c } some_t; makes it work like enum with tag
Question:
if I haven’t yet described all reasonable use cases, what for anonymous enums should be used?
In C (but not in C++),
enumcan be [ab]used to defineintconstants.For example, given this declaration:
MAXis not a constant expression, it’s the name of a read-only object. That means you can’t use it in a case label, as the size of an array declared at file scope or withstatic, or in any other context requiring a constant expression.But if you write:
then
MAXis a constant expression of typeint, usable in any context where you could use the constant1024.Of course you could also write:
but there are disadvantages to using the preprocessor: the identifier isn’t scoped the way it would be given an ordinary declaration, for example.
The drawback is that such a constant can only be of type
int.C++ has different rules; enumeration constants are of the enumerated type, not
int, but you can use declared constant objects as constant expressions (as long as the initializer is a constant expression).To address the original question, when you use an
enumdeclaration to create constants like this, there’s no point in having either a tag or a typedef, since you’ll never use the type itself.Background: This:
creates a type
enum fooand constantszero,one, andtwo. In C, the constants are always of typeint, which is admittedly odd, and the initialization ofobjinvolves an implicit conversion frominttoenum foo.In C++, the type
enum foocan also be referred to as justfoo, and the constants are of typeenum foo(which is compatible with some integer type, not necessarilyint).