tl; dr Версия
Каким образом типы данных констант перечисления гарантированно будут NSUInteger вместо unsigned int при объявлении перечисления таким образом:
enum {
NSNullCellType = 0,
NSTextCellType = 1,
NSImageCellType = 2
};
typedef NSUInteger NSCellType;
Typedef для NSUInteger, похоже, никоим образом не привязан к объявлению перечисления.
Полная версия
Я читал 64-битное руководство по переходу для какао от Apple. для некоторых рекомендаций по значениям перечисления, и я ушел с вопросом. Вот (длинная) цитата из раздела Константы перечисления, выделено мной:
Проблема с константами перечисления (enum) заключается в том, что их типы данных часто неопределенны. Другими словами, константы перечисления не являются предсказуемо беззнаковыми int. При использовании перечислений, построенных традиционным способом, компилятор фактически устанавливает базовый тип на основе того, что он находит. Базовый тип может быть (подписанным) int или даже длинным. Возьмем следующий пример:
type enum {
MyFlagError = -1,
MyFlagLow = 0,
MyFlagMiddle = 1,
MyFlagHigh = 2
} MyFlagType;
Компилятор просматривает это объявление и, найдя отрицательное значение, присвоенное одной из констант-членов, объявляет базовый тип перечисления int. Если диапазон значений для членов не помещается в int или unsigned int, тогда базовый тип автоматически становится 64-битным (длинным). Таким образом, базовый тип величин, определенных как перечисления, может незаметно изменять размер в соответствии со значениями в перечислении. Это может произойти независимо от того, компилируете ли вы 32-битную или 64-битную версию. Излишне говорить, что такая ситуация создает препятствия для двоичной совместимости.
В качестве решения этой проблемы Apple решила более четко указать тип перечисления в Cocoa API. Вместо объявления аргументов в терминах перечисления файлы заголовков теперь отдельно объявляют тип для перечисление, размер которого можно указать. Члены перечисления и их значения объявляются и присваиваются, как и раньше. Например, вместо этого:
typedef enum {
NSNullCellType = 0,
NSTextCellType = 1,
NSImageCellType = 2
} NSCellType;
вот теперь это:
enum {
NSNullCellType = 0,
NSTextCellType = 1,
NSImageCellType = 2
};
typedef NSUInteger NSCellType;
Тип перечисления определяется в терминах NSInteger или NSUInteger, чтобы сделать базовый тип перечисления 64-разрядным, совместимым с 64-разрядными архитектурами.
Мой вопрос таков: учитывая, что typedef явно не привязан к объявлению перечисления, как узнать, являются ли их типы данных unsigned int или NSUInteger?