15

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

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

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

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

那么,该类型是什么,我该如何使用它,例如,在格式字符串中?

4

4 回答 4

18

C99,TC3 读取:

6.4.4.4 §2:

整数字符常量是包含在单引号中的一个或多个多字节字符的序列,如 'x'。[...]

6.4.4.4 §10:

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

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


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

整数字符常量是包含在单引号中的一个或多个多字节字符的序列,如 'x' 或 'ab'。[...]

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

于 2009-02-14T01:26:09.393 回答
6

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

您可以将枚举用于正常比较/分配目的。与任何枚举一样,基础类型是整数。

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

于 2009-02-14T01:10:47.513 回答
2

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

当使用多于一个字符的字符常量声明整数时,它对开发该常量的机器的字节顺序很敏感。由于所有原始 Mac API 都在 PPC 或更早的机器上,它们相对于 Intel Little-Endian机器是倒退的。

如果您只是为英特尔构建,您可以手动反转顺序。

如果您正在构建通用二进制文件,则需要使用翻转功能,例如CFSwapInt32BigToHost

如果不更正这些代码,您将得到只能在 PowerPC 机器上运行的代码,而不管是否存在编译器错误。

于 2009-02-14T02:22:53.440 回答
0

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

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

编辑:抱歉,显然它是有效的 C。我只在 Mac 代码中显示它们,所以错误地认为它是 Apple 特定的。

于 2009-02-14T01:20:20.313 回答