C 语言中,enum(枚举)类型的大小并没有固定的标准值,它取决于编译器实现和目标系统。根据 C 标准,enum 的大小通常与 int 相同,但实际情况可能有所不同。在编写可移植的 C 代码时,应当使用 sizeof(enum) 检查 enum 在目标平台上的实际大小,而不要假设它总是 4 字节。

1、C 标准对 enum 大小的规定

C90/C99/C11 规定,根据 C 标准(C90、C99、C11)。

1)枚举类型的大小不固定,但必须足以容纳所有枚举成员的值。

2)枚举的底层类型通常是 int,但编译器可以选择其他合适的整数类型(如 charshort)。

3)可以使用 sizeof(enum myEnum) 来确定 enum 在特定平台上的大小。

2、enum 在不同系统中的大小

在不同的系统和编译器下,enum 的大小可能不同:

系统

编译器

sizeof(enum)

16-bit(老旧系统)

Turbo C

2 字节

32-bit Linux/Windows

GCC / MSVC

4 字节

64-bit Linux/macOS

GCC / Clang

4 字节

64-bit Windows

MSVC

4 字节

嵌入式系统

Keil / IAR

取决于优化策略(可能是 1, 2, 或 4 字节)

通常,在 32 位和 64 位系统上,enum 默认大小是 4 字节,但编译器可能会优化它,使其更小。

3、检查 enum 的大小

可以使用 sizeof 来检查 enum 的大小。

#include <stdio.h>

enum Colors { RED, GREEN, BLUE };

int main() {
    printf("Size of enum Colors: %zu bytes\n", sizeof(enum Colors));
    return 0;
}

4、enum 的大小可能变化的情况

虽然 enum 默认通常是 int 的大小,但在某些情况下,它的大小可能会发生变化。

1)使用显式赋值的枚举

如果枚举值超出了 int 的范围,编译器可能会使用更大的数据类型。

#include <stdio.h>

enum LargeEnum {
    SMALL = 1,
    BIG = 2147483648  // 超出 `int` 范围
};

int main() {
    printf("Size of enum LargeEnum: %zu bytes\n", sizeof(enum LargeEnum));
    return 0;
}

2)在某些编译器上使用优化

某些编译器允许使用 -fshort-enums 选项来让 enum 使用最小所需的存储空间。启用 -fshort-enums后,编译器可能会选择 charshort 作为 enum 的底层类型。

#include <stdio.h>

enum SmallEnum { A = 1, B = 2, C = 3 };

int main() {
    printf("Size of SmallEnum: %zu bytes\n", sizeof(enum SmallEnum));
    return 0;
}

3) 使用 typedef 指定枚举的大小

C11 标准支持 _Static_assert 进行检查。

#include <stdio.h>
#include <stdint.h>

typedef enum {
    ONE = 1,
    TWO = 2
} SmallEnum;

_Static_assert(sizeof(SmallEnum) == sizeof(int), "Enum size is not as expected");

int main() {
    printf("Size of SmallEnum: %zu bytes\n", sizeof(SmallEnum));
    return 0;
}

5、在结构体中使用 enum

如在结构体中使用 enum,它的大小仍然可能受编译器优化的影响。

#include <stdio.h>

enum Status { OK, ERROR };

struct Test {
    enum Status s;
    int value;
};

int main() {
    printf("Size of struct Test: %zu bytes\n", sizeof(struct Test));
    return 0;
}