39 votes

valeurs enum: NSInteger ou int?

tl;dr Version

Comment sont les types de données d'un enum constantes garantie à NSUInteger au lieu de unsigned int lors de la déclaration d'un enum ainsi:

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

La définition de type de NSUInteger ne semble pas être liée à la déclaration d'enum en aucune façon.

Version Complète

Je lisais par le biais d'Apple 64 Bits Guide de Transition pour le Cacao pour quelques conseils sur les valeurs de l'enum et je suis reparti avec une question. Voici un (long) citation de l' Énumération des Constantes de l'article, l'accent de la mine:

Un problème avec l'énumération (enum) constantes, c'est que leurs types de données sont souvent indéterminée. En d'autres termes, enum constantes ne sont pas, de manière prévisible, unsigned int. Avec classiquement construit énumérations, le compilateur définit le type sous-jacent basé sur ce qu'il trouve. Le type sous-jacent peut être (signé) int ou même long. Prenons l'exemple suivant:

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

Le compilateur regarde cette déclaration et, trouver une valeur négative attribuée à l'un des membres de constantes, déclare le type sous-jacent de l'énumération de type int. Si la plage de valeurs pour les membres ne rentre pas dans un int ou unsigned int, puis le type de base en silence devient 64 bits (long). Le type de base de quantités définies comme les énumérations peuvent donc changer en silence la taille pour être en accord avec les valeurs de l'énumération. Cela peut se produire si vous êtes à la compilation de 32-bits ou 64-bits. Inutile de dire que cette situation représente un obstacle pour la compatibilité binaire.

Comme un remède à ce problème, Apple a décidé d'être plus explicite sur le type d'énumération dans l'API Cocoa. Au lieu de déclarer les arguments en termes de l'énumération, les fichiers d'en-tête maintenant séparément déclarer un type de l'énumération, dont la taille peut être spécifié. Les membres de l'énumération et de leurs valeurs déclarées et affecté comme avant. Par exemple, au lieu de ceci:

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

il est maintenant à ceci:

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

Le type d'énumération est définie en termes de NSInteger ou NSUInteger pour en faire la base de l'énumération de type 64 bits sur des architectures 64 bits.

Ma question est la suivante: étant donné que la définition de type ne semble pas être liée explicitement à la déclaration d'enum, comment on sait si leurs types de données sont unsigned int ou NSUInteger?

54voto

Cœur Points 1538

Il existe maintenant ce Xcode 4.5 de départ:

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

17voto

javienegas Points 343

Je lance un test sur le simulateur de sorte que l'intention de l'essai est de vérifier la taille des différents types d'entiers. Pour cela, le résultat d' sizeof a été imprimé dans la console. J'ai donc tester cette enum valeurs:

      
typedef enum {
    TLEnumCero = 0,
    TLEnumOne = 1,
    TLEnumTwo = 2
} TLEnum;

typedef enum {
    TLEnumNegativeMinusOne = -1,
    TLEnumNegativeCero = 0,
    TLEnumNegativeOne = 1,
    TLEnumNegativeTwo = 2
} TLEnumNegative;

typedef NS_ENUM(NSUInteger, TLUIntegerEnum) {
    TLUIntegerEnumZero = 0,
    TLUIntegerEnumOne = 1,
    TLUIntegerEnumTwo = 2
};

typedef NS_ENUM(NSInteger, TLIntegerEnum) {
    TLIntegerEnumMinusOne = -1,
    TLIntegerEnumZero = 0,
    TLIntegerEnumOne = 1,
    TLIntegerEnumTwo = 2
};

Le Code De Test:


    NSLog(@"sizeof enum: %ld", sizeof(TLEnum));
    NSLog(@"sizeof enum negative: %ld", sizeof(TLEnumNegative));
    NSLog(@"sizeof enum NSUInteger: %ld", sizeof(TLUIntegerEnum));
    NSLog(@"sizeof enum NSInteger: %ld", sizeof(TLIntegerEnum));

Résultat pour iPhone Retina de 4 pouces) Simulateur:


sizeof enum: 4
sizeof enum negative: 4
sizeof enum NSUInteger: 4
sizeof enum NSInteger: 4

Résultat pour iPhone Retina de 4 pouces, 64 bits) Simulateur:


sizeof enum: 4
sizeof enum negative: 4
sizeof enum NSUInteger: 8
sizeof enum NSInteger: 8

Conclusion

Un générique enum peut être un int ou unsigned int types de 4 octets pour 32 ou 64 bits. Comme nous le savons déjà NSUInteger et NSInteger 4 octets pour les 32 bits et 8 octets, 64 bits compilateur pour iOS.

7voto

uliwitness Points 2085

Ces deux déclarations distinctes. Le typedef garantit que, lorsque vous utilisez ce type, vous obtenez toujours une NSUInteger.

Le problème avec un enum n'est pas qu'il n'est pas assez grande pour contenir la valeur. En fait, la seule garantie que vous obtenez pour un enum est que sizeof(enum Toto) est assez grand pour tenir quelles que soient les valeurs que vous avez actuellement définies dans l'enum. Mais sa taille peut changer si vous ajoutez une autre constante. C'est pourquoi Apple ne l'séparé définition de type, de maintenir binaire de la stabilité de l'API.

2voto

hatfinch Points 2292

Les types de données des constantes enum ne sont pas garantis d'être NSUInteger , mais ils sont également garantis d'être transtypés en NSUInteger chaque fois que vous les utilisez via NSCellType .

En d'autres termes, la déclaration stipule que, bien que les valeurs de l'énum correspondent actuellement à unsigned int , la mémoire qui leur est réservée lors de l'accès via NSCellType devrait être un NSUInteger .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X