C语言枚举的作用是什么?

我在知乎上看到这个问题,一开始,也有一些疑惑,后面查了一些资料,对于这个问题,简单的说一下我的看法。

枚举有多大

枚举类型到底有多大,占多少空间呢?这个要具体情况具体分析,编译器会视情况而定。

下面是我测试用的编译器版本。

bash 复制代码
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

当我写下这段代码的时候,实际的输出会是多少呢

有人会说是 1,有人会说是 4,我最终运行的确实是4

输出结果

但是这个结果并不是唯一的,它取决于你的编译器,另外还取决于编译器参数,gcc这里有个编译器参数 -fshort-enums,如果我们在编译的时候加上这个,那么编译出来是什么呢?

短枚举的输出结果

最终结果变成了1

现在我在原先的代码中,加入CMD_MAX_16BIT = 0xFFFF,下面看看输出结果是多少。

增带值范围

运行输出结果如下:

输出结果

是的,它变成了2。因此我们可以得出结论就是:

编译器将为枚举分配足够的内存大小,来保存我们所声明的任何值。所以,如果我们的代码中只使用低于 256(8位的范围是0~255) 的值,我们的枚举应该是 8 位宽,也就是一个字节,而后面的0xFFFF显然是16位,两个字节,所以最终输出为2

为此我参考了一下gcc user manual,如下;

https ://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

复制代码

-fshort-enums

Allocate to an enum type only as many bytes as it needs for the declared range of possible values. Specifically, the enum type is equivalent to the smallest integer type that has enough room.

Warning: the -fshort-enums switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.

所以,我们需要明确的是编译器是否会默认执行 -fshort-enums这个命令,大多数是不会的,这里我还测试了一些clang,具体结果和gcc相同。

但是在嵌入式编程中需要注意,这里我查了一下,IAR的编译器默认会执行 -fshort-enums

电脑上没有IAR,这里我参考了IAR 的 ARM C 编译器的文档IAR C/C++ Development Guide

可以看到enum类型默认的规定,如果要强制为int类型的话,需要编译的时候提那就--enum_is_int的编译参数,如下所示;

枚举类型

所以这里为了避免编译器的优化,以及不同的硬件平台和不同编译器,从而导致枚举分配内存空间的变化,所以上述增加了一个0xFFFFFFFF,强制编译器为枚举分配4个字节的空间。

设置最大范围为4字节

最终的输出结果都是4,如下图所示;

输出结果比较

看来虽然是一个很小的知识点,但是这中间的坑还真不少。

相关推荐
七七&5565 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
java坤坤5 小时前
GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
开发语言·后端·golang
元清加油5 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
健康平安的活着6 小时前
java之 junit4单元测试Mockito的使用
java·开发语言·单元测试
No0d1es6 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
DjangoJason7 小时前
C++ 仿RabbitMQ实现消息队列项目
开发语言·c++·rabbitmq
m0_480502648 小时前
Rust 入门 KV存储HashMap (十七)
java·开发语言·rust
大阳1238 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
YA3338 小时前
java基础(九)sql基础及索引
java·开发语言·sql
奇树谦9 小时前
QT|windwos桌面端应用程序开发,当连接多个显示器的时候,如何获取屏幕编号?
开发语言·qt