枚举值的类型是什么?

我正在使用Apple的ScriptingBridge框架,并为iTunes生成了一个包含以下几个enum的头文件:

 typedef enum { iTunesESrcLibrary = 'kLib', iTunesESrcIPod = 'kPod', iTunesESrcAudioCD = 'kACD', iTunesESrcMP3CD = 'kMCD', iTunesESrcDevice = 'kDev', iTunesESrcRadioTuner = 'kTun', iTunesESrcSharedLibrary = 'kShd', iTunesESrcUnknown = 'kUnk' } iTunesESrc; 

我的理解是enum值必须是整数,但这个定义似乎违反了这个规则。 此外,似乎将这些enum值视为整数(例如,在NSPredicate )并不是正确的事情。

我将上面的enum声明添加到具有空main函数的C文件中,并使用i686-apple-darwin9-gcc-4.0.1 。 因此,虽然这些类型的enum可能不符合C标准(正如Parappa在下面指出的那样),但它们至少被gcc编译成某种类型。

那么,那种类型是什么,以及如何在格式字符串中使用它?

C99,TC3读取:

6.4.4.4§2:

整数字符常量是用单引号括起来的一个或多个多字节字符的序列,如’x’。 […]

6.4.4.4§10:

整数字符常量的类型为int。 包含映射到单字节执行字符的单个字符的整数字符常量的值是解释为整数的映射字符的表示的数值。 包含多个字符(例如,’ab’)的整数字符常量的值,或包含未映射到单字节执行字符的字符或转义序列的值是实现定义的。 如果整数字符常量包含单个字符或转义序列,则其值是当char为char的类型为单个字符或转义序列的对象转换为int类型时生成的值。

在大多数实现中,使用最多4个单字节字符的整数字符常量是安全的。 但是,不同系统(字节序?)的实际值可能不同。


这实际上已在ANSI-C89标准3.1.3.4节中定义:

整数字符常量是用单引号括起来的一个或多个多字节字符的序列,如’x’或’ab’。 […]

整数字符常量的类型为int。 包含映射到基本执行字符集成员的单个字符的整数字符常量的值是解释为整数的映射字符的表示的数值。 包含多个字符或包含未在基本执行字符集中表示的字符或转义序列的整数字符常量的值是实现定义的。 特别地,在char类型具有与signed char相同的值范围的实现中,单字符整数字符常量的高位比特位置被视为符号位。

单引号表示字符,而不是C中的字符串。因此每个枚举都有一个32位值,由四个字符的字符代码组成。 实际值将取决于字符编码,但我假设8位字符。 注意没有附加\ 0。

您可以使用枚举进行常规比较/分配。 与任何枚举一样,基础类型是整数。

我已经多次在嵌入式系统中使用这种技术来创建4个字符“名称”,这些名称在hex转储/调试器上下文中是人类可读的。

如前所述,这些是使用字符常量声明的整数。

当使用多于一个字符的字符常量声明整数时,它对开发了常量的机器的字节顺序很敏感。 由于所有原始的Mac API都在PPC或更早的机器上,因此它们与英特尔Little-Endian机器相反 。

如果您只是为英特尔构建,则可以手动撤消订单。

如果要构建通用二进制文件,则需要使用翻转function,例如CFSwapInt32BigToHost 。

无法纠正这些代码将为您留下只能在PowerPC机器上运行的代码,无论编译器错误是否存在。

这是C的Apple扩展,它基本上将这些枚举转换为:

 typedef enum { iTunesESrcLibrary = 'k'<<24 | 'L'<<16 | 'i'<<8 | 'b', ... } 

编辑:对不起,显然它是有效的C.我只是在Mac代码中看起来,所以错误地认为它是Apple特有的。