在C中指定枚举类型的大小
已经阅读了这个相关的问题 ,但正在寻找一些更具体的东西。
- 有没有办法告诉你的编译器你想要你的枚举有多宽?
- 如果是这样,你怎么做? 我知道如何在C#中指定它; 它是否同样在C中完成?
- 它甚至值得做吗? 当枚举值传递给函数时,它是否会作为
int
-sized值传递?
有没有办法告诉你的编译器你想要你的枚举有多宽?
一般情况下没有。 不在标准C.
它甚至值得做吗?
这取决于具体情况。 如果你在谈论将参数传递给函数,那么不,这是不值得做的(见下文)。 如果它是在从枚举类型构建聚合时节省内存,那么它可能值得做。 但是,在C中,您只需在聚合中使用适当大小的整数类型而不是枚举类型。 在C(而不是C ++)中,枚举类型和整数类型几乎总是可以互换的。
当枚举值传递给函数时,它是否会作为int大小的值传递?
如今,许多(大多数)编译器将所有参数作为给定硬件平台的自然字大小的值传递。 例如,在64位平台上,许多编译器将所有参数作为64位值传递,而不管它们的实际大小如何,即使int
类型在该平台上有32位(因此,它通常不会作为“int”传递这样一个平台上的“价值”。 因此,尝试针对参数传递目的优化枚举大小是没有意义的。
如果您使用GCC,我相信会有一面旗帜。
-fshort,枚举
您可以通过定义适当的值来强制它至少达到一定的大小。 例如,如果您希望将枚举存储为与int
相同的大小,即使所有值都适合char
,也可以执行以下操作:
typedef enum { firstValue = 1, secondValue = 2, Internal_ForceMyEnumIntSize = MAX_INT } MyEnum;
但请注意,行为可能取决于实现。
正如您所注意到的,将这样的值传递给函数将导致它无论如何都会扩展为int,但如果您在数组或结构中使用类型,则大小将很重要。 如果你真的关心元素大小,你应该使用int8_t
, int32_t
等类型。
如果枚举是结构的一部分,还有另一种方法:
struct something { :0; enum whatever field:CHAR_BIT; :0; };
:0; 如果枚举字段被普通字段包围,则可以省略。 如果之前有另一个位域,则:0将强制字节对齐到其后的字段的下一个字节。
它取决于为枚举分配的值。
例如:如果存储的值大于2 ^ 32-1,则为整个枚举分配的大小将更改为下一个大小。
将0xFFFFFFFFFFFF值存储到枚举变量,如果尝试在32位环境中编译,它将发出警告(舍入警告)在64位编译中,它将成功,并且分配的大小将为8个字节。
另一种方法是将联合内容中的枚举转换为如下:
union char_size { char a; enum { a = 1, b = 2, } val; };
这样做会强制编译器将enum放入char中。