不同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
相关产品推荐
相关产品推荐

