在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_tint32_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中。