我正在使用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编译为某些类型。
那么,该类型是什么,以及如何在格式字符串中使用它?
答案 0 :(得分:18)
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。的价值 整数字符常量,包含映射的单个字符 成为基本执行字符集的成员是数字 解释为的映射字符表示的值 整数。包含更多的整数字符常量的值 不是一个字符,或者不包含字符或转义序列 在基本执行字符集中表示,是 实现定义。特别是,在其中的实现中 type char与signed char具有相同的值范围,即高位 单字符整数字符常量的位位置是 被视为一个标志位。
答案 1 :(得分:6)
单引号表示字符,而不是C中的字符串。因此每个枚举都有一个32位值,由四个字符的字符代码组成。实际值将取决于字符编码,但我假设8位字符。注意没有附加\ 0。
您可以使用枚举进行常规比较/分配。与任何枚举一样,基础类型是整数。
我已经多次在嵌入式系统中使用这种技术来创建在十六进制转储/调试器上下文中人类可读的4个字符“名称”。
答案 2 :(得分:2)
如前所述,这些是使用字符常量声明的整数。
当使用多个字符的字符常量声明整数时,它对开发了常量的机器的byte order敏感。由于所有原始的Mac API都在PPC或更早的机器上,因此它们与英特尔Little-Endian机器相反。
如果您只是为英特尔打造,您可以手动撤销订单。
如果您要构建通用二进制文件,则需要使用flipping function,例如CFSwapInt32BigToHost。
如果无法纠正这些代码,将为您提供只能在PowerPC计算机上运行的代码,无论编译错误是什么。
答案 3 :(得分:0)
这是C的Apple扩展,它基本上将这些枚举转换为:
typedef enum {
iTunesESrcLibrary = 'k'<<24 | 'L'<<16 | 'i'<<8 | 'b',
...
}
编辑:对不起,显然它是有效的C.我只是在Mac代码中看起来,所以错误地认为它是Apple特有的。