You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不同enum类型的取值范围及相互可转换的条件是什么?

在什么条件下可以从一种枚举类型转换为另一种?

我们来看以下代码:

#include <stdio.h>

int main(void) {
  enum enum_tag_1 { language } c = language;
  enum enum_tag_2 { lawyer = 256 } d = lawyer;
  d = c;
  c = 2;
  printf("%d\n", c);
  printf("%d\n", d);
}

我们可以提出诸如c = 2;和d = c;这类语句是否能保证正常运行的问题。

C17标准(草案,6.7.2.2)规定:

¶3 枚举符列表中的标识符被声明为类型为int的常量。[...]
¶4 每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但必须能够表示该枚举的所有成员的值。[...]

也就是说,枚举类型本质上是由实现选择的、足以容纳给定枚举符列表的一种可能为实现定义的整数类型,其所有枚举符的类型必须为int。

具体来说:

  • enum enum_tag_1是一种可能为实现定义的类型,足以容纳int类型的0。它可以是_Bool或取值范围为{-1, 0, 1}的自定义类型。因此赋值语句c = 2;不一定合法。
  • enum enum_tag_2是一种可能为实现定义的类型,足以容纳int类型的256。这意味着它至少可以容纳范围[0, 1, ..., 511]的值(但不一定能容纳512)。因此赋值语句d = language(值为0)始终合法。上述代码中的d = c;是合法的,但并非所有enum enum_tag_1类型的值都能赋值给enum enum_tag_2,因为前者可能是signed(有符号)类型,而后者可能是unsigned(无符号)类型。
  • 尽管enum enum_tag_1和enum enum_tag_2的枚举常量只能取适合int类型的值,但实现可以将这些类型定义得足够大,以便可以为它们分配非常大的数值,例如:
    c = −9223372036854775808;
    d = 18446744073709551615;

这基于整数类型的取值范围始终为[0, 2N-1](无符号)或[-2N, 2N-1](有符号)的事实,其中N是值位的数量(C17标准草案,6.2.6.2 ¶1-2)。

那一般情况呢?似乎enum类型之间的相互转换取决于实现选择的类型取值范围,这使得答案具有实现依赖性。


内容的提问来源于stack exchange,提问作者Lover of Structure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:27:14