2r2w 2r2w - 2 months ago 6
C Question

in which situations anonymous enum should be used?

In both c and c++

could be defined with tag

enum e_smth {

or without tag

enum {

If it was defined with tag it makes sense in
statements in both c and c++ :

e_smth some_var;
....//do some stuff with some_var
switch (some_var)
case smth_one:
case smth_two:

will produce
warning if this will be compiled with gcc or g++.

It makes sense in functions declarations and variables initialization in c++ :

e_smth var;

Will produce
error if compiled with g++.

Both types with or without tag could be used as one file
macro without parameters.


could be used as one file
macro 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


if I haven't yet described all reasonable use cases, what for anonymous enums should be used?


In C (but not in C++), enum can be [ab]used to define int constants.

For example, given this declaration:

const int MAX = 1024;

MAX is 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 with static, or in any other context requiring a constant expression.

But if you write:

enum { MAX = 1024 };

then MAX is a constant expression of type int, usable in any context where you could use the constant 1024.

Of course you could also write:

#define MAX 1024

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 enum declaration 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:

enum foo { zero, one, two };
enum foo obj = two;

creates a type enum foo and constants zero, one, and two. In C, the constants are always of type int, which is admittedly odd, and the initialization of obj involves an implicit conversion from int to enum foo.

In C++, the type enum foo can also be referred to as just foo, and the constants are of type enum foo (which is compatible with some integer type, not necessarily int).