enum 类型到底有多大

这里有一个问题:

#include 
typedef enum {
        CAN1 = 1,
        CAN2,
        CAN3,
        CAN4,
} Enum_8bit;
typedef enum {
        IP4 = 0x1234,
        IP5 = 0x444,
        IP6 = 0xffee,
} Enum_16bit;
void main(void)
{
        printf("Enum_8bit is %d.\n", sizeof(Enum_8bit));  
        printf("Enum_16bit is %d.\n", sizeof(Enum_16bit));
        printf("Enum_8bit element is %d.\n", sizeof(CAN1));   
        printf("Enum_16bit element is %d.\n", sizeof(IP6));   
        Enum_16bit bit16 = IP4;
        Enum_8bit bit8 = CAN1;
        printf("Enum_8bit variable is %d.\n", sizeof(bit8));
        printf("Enum_16bit variable is %d.\n"  , sizeof(bit16));
}  


 一般情况下,上面会打印的结果是什么呢?

对于一个32位的系统来说,如果你是用的GCC,而且CFLAGS是在默认的情况的话,上面输出的都是4.

Enum_8bit is 4.
Enum_16bit is 4.
Enum_8bit element is 4.
Enum_16bit element is 4.
Enum_8bit variable is 4.
Enum_16bit variable is 4.

这里为什么呢?

Enum_8bit 和Enum_16bit在这里,只是一个申明的数据类型,它和int, char一样,只不过是我们用户自己申请的数据类型,它的大小就是它的变量所占有的空间的大小。而不是所有它的element总合的大小。

我的系统是一个64位的系统,为什么这里输出的是4个字节大小,而不是8个字节的大小者 2个字节呢?这里因为在C的standard中:

6.7.2.2 Enumeration specifiers
[...]
Constraints
The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
[...]
Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.
enum类型就是一个int 类型,但它占用空间到底有多大呢? 我没有找到相关的文档说明,我个人认为这个取决于你的系统的字节对齐方式和enum中各个元素所给于的值的大小,像上面,我的例子,Enum_8bit 每一个元素的值都没有超过8bit,但及时这样,因为我的系统是以4字节对齐的,C  compiler 分配了4个字节大小给这个类型。Enum_16bit也一样,以四字节对齐。

这不是有点浪费空间吗?能不能缩短它们的大小,让它们根据各自元素的大小来分配大小呢?

是可以的,我们可以用  -fshort-enums,强制改变enum的大小。

如:gcc  -g -O2   -o -fshort-enums enum_test enum-test.o 

Enum_8bit is 1.
Enum_16bit is 2.
Enum_8bit element is 4.
Enum_16bit element is 4.
Enum_8bit variable is 1.
Enum_16bit variable is 2.
但是奇诡,为什么Enum_8bit和Enum_16bit中的元素还是4字节呢?原来对于enum来说,它自己的每一个element就是一个正型,大小取决于它的值,而默认是四字节对齐。

如我把上面的程序改成这样:

#include                                                                                                                   
typedef enum {
        CAN1 = 1,
        CAN2,
        CAN3,
        CAN4,
} Enum_8bit;
typedef enum {
        IP4 = 0x1234,
        IP5 = 0x444,
        IP6 = 0xffee,
} Enum_16bit;
typedef enum {
        VP1 = 0x1234,
        VP2 = 0x444,
        VP3 = 0xffeeEEEEEEEEEDDE,
} Enum_32bit;
void main(void)
{
        printf("Enum_8bit is %d.\n", sizeof(Enum_8bit));  
        printf("Enum_16bit is %d.\n", sizeof(Enum_16bit));
        printf("Enum_8bit element is %d.\n", sizeof(CAN1));   
        printf("Enum_16bit element is %d.\n", sizeof(IP4));   
        printf("Enum_32bit 64bits element is %d.\n", sizeof(VP3));   
        printf("Enum_32bit 16bits element is %d.\n", sizeof(VP2));   
        Enum_16bit bit16 = IP4;
        Enum_8bit bit8 = CAN1;
        printf("Enum_8bit variable is %d.\n", sizeof(bit8));
        printf("Enum_16bit variable is %d.\n"  , sizeof(bit16));
}
在有 -fshort-enums 的情况下:

gcc  -g -O2 -fshort-enums   -o enum_test enum-test.o 
它的输出结果是:

Enum_8bit is 1.
Enum_16bit is 2.
Enum_8bit element is 4.
Enum_16bit element is 4.
Enum_32bit 64bits element is 8.
Enum_32bit 16bits element is 4.
Enum_8bit variable is 1.
Enum_16bit variable is 2.
在没有 -fshort-enums的情况下:

Enum_8bit is 4.
Enum_16bit is 4.
Enum_8bit element is 4.
Enum_16bit element is 4.
Enum_32bit 64bits element is 8.
Enum_32bit 16bits element is 4.
Enum_8bit variable is 4.
Enum_16bit variable is 4.




你可能感兴趣的:(linux)