ZHCU820Y September 2004 – June 2021
在以下声明中,enum e
是一个枚举类型。每一个 a
和 b
均为枚举常量。
enum e { a, b=N };
每个枚举类型均会被分配一个可保存所有枚举常量的整型。这个整型是“基础类型”。每个枚举常量的类型也是整型,并且在 C 语言中可能并不是相同的类型。请务必注意枚举类型的基础类型 与枚举常量类型 之间的区别。
为枚举类型和每个枚举常量选择的大小和符号取决于枚举常量的值以及是针对 C 还是 C++ 进行编译。C++11 允许您为枚举类型指定具体的类型;如果提供了此种类型,则会使用该类型,并且此段的其余部分不适用。
在 C++ 模式中,编译器允许枚举常量最高为最大整型(64 位)。C 标准规定,所有采用严格符合 C 代码的枚举常量 (C89/C99/C11) 均必须具有适合“int”类型的值;不过,作为扩展,您甚至可以在 C 模式下使用大于“int”的枚举常量。
您可以通过使用 --enum_type 命令行选项和/或通过使用属性,控制挑选枚举类型的策略。如果您使用 --enum_type=packed 选项(默认),则编译器会使用可用作枚举类型的最小类型。如果您使用 --enum_type=unpacked 选项(默认),则编译器会使用不小于“int”的最小类型。您可以使用“packed”或“unpacked”属性来针对单个枚举类型设置策略;这会覆盖命令行选项的值。
例如,即使在命令行中指定了 --enum_type=unpacked,这个枚举类型也将会是无符号字符型。
enum { a, b, c } __attribute__((packed));
即使在命令行中指定了 --enum_type=packed,这个枚举类型也将会是无符号整型。
enum { a, b, c } __attribute__((unpacked));
您可以在头文件中使用枚举类型的 packed/unpacked 属性来确保枚举类型的大小始终相同,即使在命令行中更改了 --enum_type 选项也是如此。
对于枚举类型,编译器会选择以下列表中足够大且符号正确、能够表示所有枚举常量值的第一个类型。 不使用“short”类型,因为其与“int”类型大小相同。
例如,默认情况 (--enum_type=unpacked) 下,下面这个枚举类型将会以“unsigned int”作为其基础类型:
enum ui { a, b, c };
但下面这个将会以“signed int”作为其基础类型:
enum si { a, b, c, d = -1 };
而下面这个将会以“signed long”作为其基础类型:
enum sl { a, b, c, d = -1, e = UINT_MAX };
对于 C++,枚举常量全都具有与枚举类型相同的类型。
对于 C,则会根据它们的值来为枚举常量分配类型。所有值可以放入“int”的枚举常量都会被指定“int”类型,即使枚举类型的基础类型小于“int”也是如此。所有不能放入“int”的枚举常量都会被指定与枚举类型的基础类型相同的类型。这意味着,一些枚举常量可能与枚举类型具有不同的大小和符号。