Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in which situations anonymous enum should be used?

Tags:

c++

c

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 #define 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

Question:

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

like image 828
2r2w Avatar asked Apr 14 '12 20:04

2r2w


1 Answers

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).

like image 141
Keith Thompson Avatar answered Oct 22 '22 17:10

Keith Thompson