Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enum values: NSInteger or int?

tl;dr Version

How are the data types of an enum's constants guaranteed to be NSUInteger instead of unsigned int when declaring an enum thusly:

enum {     NSNullCellType = 0,     NSTextCellType = 1,     NSImageCellType = 2 }; typedef NSUInteger NSCellType; 

The typedef to NSUInteger does not appear to be tied to the enum declaration in any way.

Full Version

I was reading through Apple's 64-Bit Transition Guide for Cocoa for some guidance on enum values and I came away with a question. Here's a (lengthy) quote from the Enumeration Constants section, emphasis mine:

A problem with enumeration (enum) constants is that their data types are frequently indeterminate. In other words, enum constants are not predictably unsigned int. With conventionally constructed enumerations, the compiler actually sets the underlying type based on what it finds. The underlying type can be (signed) int or even long. Take the following example:

type enum {     MyFlagError = -1,     MyFlagLow = 0,     MyFlagMiddle = 1,     MyFlagHigh = 2 } MyFlagType; 

The compiler looks at this declaration and, finding a negative value assigned to one of the member constants, declares the underlying type of the enumeration int. If the range of values for the members does not fit into an int or unsigned int, then the base type silently becomes 64-bit (long). The base type of quantities defined as enumerations can thus change silently size to accord with the values in the enumeration. This can happen whether you're compiling 32-bit or 64-bit. Needless to say, this situation presents obstacles for binary compatibility.

As a remedy for this problem, Apple has decided to be more explicit about the enumeration type in the Cocoa API. Instead of declaring arguments in terms of the enumeration, the header files now separately declare a type for the enumeration whose size can be specified. The members of the enumeration and their values are declared and assigned as before. For example, instead of this:

typedef enum {     NSNullCellType = 0,     NSTextCellType = 1,     NSImageCellType = 2 } NSCellType; 

there is now this:

enum {     NSNullCellType = 0,     NSTextCellType = 1,     NSImageCellType = 2 }; typedef NSUInteger NSCellType; 

The enumeration type is defined in terms of NSInteger or NSUInteger to make the base enumeration type 64-bit capable on 64-bit architectures.

My question is this: given that the typedef doesn't appear to be tied explicitly to the enum declaration, how does one know if their data types are unsigned int or NSUInteger?

like image 796
Michael Fey Avatar asked Dec 13 '11 22:12

Michael Fey


People also ask

Is enum value an int?

By default, the type for enum elements is int. We can set different type by adding a colon like an example below. The different types which can be set are sbyte, byte, short, ushort, uint, ulong, and long.

Is enum string or int?

The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.

Should I use enum or int?

There are a very small number of places where using int flags is still preferable in modern Java code, but in most cases you should prefer to use an enum , due to the type safety and expressiveness that they offer.

What type are enum values?

An enum type is a distinct value type (§8.3) that declares a set of named constants. declares an enum type named Color with members Red , Green , and Blue .


1 Answers

There is now NS_ENUM starting Xcode 4.5:

typedef NS_ENUM(NSUInteger, NSCellType) {     NSNullCellType = 0,     NSTextCellType = 1,     NSImageCellType = 2 }; 

And you can consider NS_OPTIONS if you work with binary flags:

typedef NS_OPTIONS(NSUInteger, MyCellFlag) {     MyTextCellFlag = 1 << 0,     MyImageCellFlag = 1 << 1, }; 
like image 144
Cœur Avatar answered Sep 28 '22 04:09

Cœur