By Craig


2009-04-01 21:59:43 8 Comments

I don't think I fundamentally understand what an enum is, and when to use it.

For example:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

What is really being declared here?

13 comments

@Vincent Zgueb 2013-03-10 18:23:21

The enum (abbreviation of enumeration) is used to enumerate a set of values (enumerators). A value is an abstract thing represented by a symbol (a word). For example, a basic enum could be

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };

This enum is called anonymous because you do not have a symbol to name it. But it is still perfectly correct. Just use it like this

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;

Ok. The life is beautiful and everything goes well. But one day you need to reuse this enum to define a new variable to store myGrandFatherPantSize, then you write:

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

But then you have a compiler error "redefinition of enumerator". Actually, the problem is that the compiler is not sure that you first enum and you are second describe the same thing.

Then if you want to reuse the same set of enumerators (here xs...xxxxl) in several places you must tag it with a unique name. The second time you use this set you just have to use the tag. But don't forget that this tag does not replace the enum word but just the set of enumerators. Then take care to use enum as usual. Like this:

// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize; 
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;

you can use it in a parameter definition as well:

// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;

You could say that rewriting enum everywhere is not convenient and makes the code looks a bit strange. You are right. A real type would be better.

This is the final step of our great progression to the summit. By just adding a typedef let's transform our enum in a real type. Oh the last thing, typedef is not allowed within your class. Then define your type just above. Do it like this:

// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

@interface myClass {
   ...
   size_type myGrandMotherDressSize, myGrandFatherPantSize;
   ...
}

Remember that the tag is optional. Then since here, in that case, we do not tag the enumerators but just to define a new type. Then we don't really need it anymore.

// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;

@interface myClass : NSObject {
  ...
  size_type myGrandMotherDressSize, myGrandFatherPantSize;
  ...
}
@end

If you are developing in Objective-C with XCode I let you discover some nice macros prefixed with NS_ENUM. That should help you to define good enums easily and moreover will help the static analyzer to do some interesting checks for you before to compile.

Good Enum!

@rak appdev 2017-03-13 15:28:19

I always thought "why would anyone answer a question which is already answered and accepted". Boy, I was wrong all the time! This is the best answer and helps beginners like me!

@hburde 2012-03-15 16:31:57

An enum declares a set of ordered values - the typedef just adds a handy name to this. The 1st element is 0 etc.

typedef enum {
Monday=1,
...
} WORKDAYS;

WORKDAYS today = Monday;

The above is just an enumeration of shapeType tags.

@Vladimir Grigorov 2013-03-06 09:43:16

Apple recommends defining enums like this since Xcode 4.4:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

They also provide a handy macro NS_ENUM:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

These definitions provide stronger type checking and better code completion. I could not find an official documentation of NS_ENUM, but you can watch "Modern Objective-C" video from WWDC 2012 session here.

UPDATE: Link to official documentation here.

@vikingosegundo 2013-03-19 23:53:27

The part about "Enum Improvements" starts at 5:58

@Basil Bourque 2013-09-05 23:18:00

As commented on another answer, see explanation of Apple’s NS_ENUM macro by NSHipster: NSHipster.com/ns_enum-ns_options

@YoGiN 2014-09-07 06:40:30

This is the link to the official documentation about NS_ENUM: developer.apple.com/library/ios/releasenotes/ObjectiveC/…

@Marcus Thornton 2018-06-21 06:29:25

enum can reduce many types of "errors" and make the code more manageable

#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER

The definition has no constraints. It's simply just a substitution. It is not able to limit all conditions of the state. When the STATE is assigned to 5, the program will be wrong, because there is no matching state. But the compiler is not going to warn STATE = 5

So it is better to use like this

typedef enum SampleState {
    SampleStateGood  = 0,
    SampleStateBad,
    SampleStateOther
} SampleState;

SampleState state = SampleStateGood;

@Mani 2014-01-29 13:08:25

Update for 64-bit Change: According to apple docs about 64-bit changes,

Enumerations Are Also Typed : In the LLVM compiler, enumerated types can define the size of the enumeration. This means that some enumerated types may also have a size that is larger than you expect. The solution, as in all the other cases, is to make no assumptions about a data type’s size. Instead, assign any enumerated values to a variable with the proper data type

So you have to create enum with type as below syntax if you support for 64-bit.

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

or

typedef enum ShapeType : NSUInteger {
   kCircle,
   kRectangle,
   kOblateSpheroid
} ShapeType;

Otherwise, it will lead to warning as Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Update for swift-programming:

In swift, there's an syntax change.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }

@lal 2017-10-18 14:17:19

If need to forward declare enum (NS_ENUM): stackoverflow.com/a/42009056/342794

@Bilal Arslan 2016-03-30 09:41:17

You can use in the below format, Raw default value starting from 0, so

  • kCircle is 0,
  • kRectangle is 1,
  • kOblateSpheroid is 2.

You can assign your own specific start value.

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0

@Vivek Sehrawat 2013-12-25 06:14:40

typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

then you can use it like :-

 ShapeType shape;

and

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

now you can use it like:-

enum ShapeType shape;

@Yogeesh H T 2015-11-16 12:33:54

The Typedef is a Keyword in C and C++. It is used to create new names for basic data types (char, int, float, double, struct & enum).

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Here it creates enumerated data type ShapeType & we can write new names for enum type ShapeType as given below

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;

@user4398701 2014-12-27 22:42:40

A typedef allows the programmer to define one Objective-C type as another. For example,

typedef int Counter; defines the type Counter to be equivalent to the int type. This drastically improves code readability.

@Priyanka Naik 2014-03-16 12:45:55

enum is used to assign value to enum elements which cannot be done in struct. So everytime instead of accessing the complete variable we can do it by the value we assign to the variables in enum. By default it starts with 0 assignment but we can assign it any value and the next variable in enum will be assigned a value the previous value +1.

@Rajneesh071 2013-06-18 06:03:00

typedef is useful for redefining the name of an existing variable type. It provides short & meaningful way to call a datatype. e.g:

typedef unsigned long int TWOWORDS;

here, the type unsigned long int is redefined to be of the type TWOWORDS. Thus, we can now declare variables of type unsigned long int by writing,

TWOWORDS var1, var2;

instead of

unsigned long int var1, var2;

@Brian Mitchell 2009-04-01 22:04:21

A user defined type that has the possible values of kCircle, kRectangle, or kOblateSpheroid. The values inside the enum (kCircle, etc) are visible outside the enum, though. It's important to keep that in mind (int i = kCircle; is valid, for example).

@Adam Rosenfield 2009-04-01 22:22:20

Three things are being declared here: an anonymous enumerated type is declared, ShapeType is being declared a typedef for that anonymous enumeration, and the three names kCircle, kRectangle, and kOblateSpheroid are being declared as integral constants.

Let's break that down. In the simplest case, an enumeration can be declared as

enum tagname { ... };

This declares an enumeration with the tag tagname. In C and Objective-C (but not C++), any references to this must be preceded with the enum keyword. For example:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

In order to avoid having to use the enum keyword everywhere, a typedef can be created:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

This can be simplified into one line:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

And finally, if we don't need to be able to use enum tagname with the enum keyword, we can make the enum anonymous and only declare it with the typedef name:

typedef enum { ... } tagname;

Now, in this case, we're declaring ShapeType to be a typedef'ed name of an anonymous enumeration. ShapeType is really just an integral type, and should only be used to declare variables which hold one of the values listed in the declaration (that is, one of kCircle, kRectangle, and kOblateSpheroid). You can assign a ShapeType variable another value by casting, though, so you have to be careful when reading enum values.

Finally, kCircle, kRectangle, and kOblateSpheroid are declared as integral constants in the global namespace. Since no specific values were specified, they get assigned to consecutive integers starting with 0, so kCircle is 0, kRectangle is 1, and kOblateSpheroid is 2.

@Michael Burr 2009-04-01 22:32:08

Nice explanation - just to add one thing, struct's follow similar naming rules in C (not sure about Objective-C).

@sigjuice 2009-04-01 22:43:35

Objective-C is a proper superset of C. All the C struct naming rules in C are just as valid in Objective-C.

@user4951 2011-05-11 09:57:08

Awesome. Can I just use C++ style enum and also don't need to write enum :)

@Kevin Hoffman 2011-06-02 14:05:45

You can use C++ style enums if the file in which you declare them is a .mm file rather than a .m. Objective-C++ is absurdly powerful.

@Snowcrash 2013-04-22 11:21:06

And once you've got your head around this answer it's worth looking at the new NS_ENUM and NS_OPTIONS. Tutorial here: nshipster.com/ns_enum-ns_options and SO here: stackoverflow.com/questions/14080750/…

@NoodleOfDeath 2014-06-08 14:13:15

When would you need to give the enumeration a name? Seems to me you could always leave it anonymous?

@Jake T. 2017-02-21 16:04:43

"Finally .... are declared as integral constants in the global namespace" Does this mean I can use them outside of the file I created them in, even if it's a .m? Will it cause issues to declare the same integral constants in another anonymously typedef'ed enum in another file? Is there a recommended place to declare these types of constants that may be used commonly across your app?

Related Questions

Sponsored Content

27 Answered Questions

[SOLVED] How do I enumerate an enum in C#?

25 Answered Questions

[SOLVED] How to get an enum value from a string value in Java?

  • 2009-03-02 22:56:34
  • Malachi
  • 983307 View
  • 1798 Score
  • 25 Answer
  • Tags:   java enums

45 Answered Questions

[SOLVED] What is the preferred syntax for defining enums in JavaScript?

91 Answered Questions

8 Answered Questions

[SOLVED] How to loop through all enum values in C#?

26 Answered Questions

[SOLVED] Get int value from enum in C#

  • 2009-06-03 06:46:39
  • jim
  • 1293758 View
  • 1580 Score
  • 26 Answer
  • Tags:   c# enums casting int

24 Answered Questions

[SOLVED] Cast int to enum in C#

  • 2008-08-27 03:58:21
  • lomaxx
  • 1174123 View
  • 2849 Score
  • 24 Answer
  • Tags:   c# enums casting

11 Answered Questions

[SOLVED] What does the [Flags] Enum Attribute mean in C#?

  • 2008-08-12 04:09:16
  • Brian Leahy
  • 430742 View
  • 1298 Score
  • 11 Answer
  • Tags:   c# enums flags

14 Answered Questions

[SOLVED] Comparing Java enum members: == or equals()?

  • 2009-11-17 17:26:27
  • Matt Ball
  • 581118 View
  • 1551 Score
  • 14 Answer
  • Tags:   java enums

4 Answered Questions

[SOLVED] What is the difference between 'typedef' and 'using' in C++11?

Sponsored Content