C/C99/C++/C++x/GNU C/GNU C99中枚举的无符号性

40

枚举类型是有符号的还是无符号的?在 C/C99/ANSI C/C++/C++x/GNU C/ GNU C99 中,枚举的有符号性是否不同?

谢谢。

2个回答

32

枚举类型保证是由整数表示,但实际类型(以及其有无符号性)取决于具体实现。

你可以通过给枚举值中的一个赋负值来强制使用带符号类型表示枚举:

enum SignedEnum { a = -1 };

C++0x中,枚举类型的基础类型可以被显式地指定:

enum ShortEnum : short { a };

(C++0x还增加了对作用域枚举的支持)

为了完整起见,我将补充一下,在《C程序设计语言》第2版中,枚举器被指定为具有int类型(第215页)。 K&R不是C标准,因此它对于ISO C编译器来说并非规范,但它早于ISO C标准,因此从历史的角度来看至少很有趣。


2
gcc 实际使用的是什么符号类型? - osgx
1
@osgx:我猜这取决于枚举器的数量和它们值的范围。我真的不知道。 - James McNellis
4
C标准还规定了每个枚举常量的类型为int。但是,“枚举常量”一词指的是在enum {}块内声明的值常量。具有enum类型的变量可以具有C中的任何整数类型,例如,如果可以表示所有值,则可能是比int更短的类型。(例如,GCC有一个选项“-fshort-enums”,可精确地执行此操作。) - Arkku
“enumerator”这个术语通常被理解为枚举常量。据我所知,在enum{}内部,它们从未具有比int更小的类型,因为编译器还不知道接下来会有什么值。 - MSalters
@MSalters @Arkku:没错,在C语言中,枚举常量始终是“int”类型。而在C++中,它们与其初始化程序具有相同的类型,因此可以是任何整数类型。 - James McNellis
14
GCC在编译时决定对“枚举”应用哪种符号。我有一个包含从零开始的值的枚举器,并在函数内检查该枚举器的值是否小于零(用作数组索引)。GCC会给出一个警告:“avServerApi.c:23: warning: comparison of unsigned expression < 0 is always false”。如果我在“枚举”中放入一个虚拟的“-1”,那么警告就会消失,因为此时枚举器是有符号的。 - Matt Clarkson

0

这是一个老问题...但我刚刚发现了这个:

typedef unsigned ENUMNAME;  // this makes it unsigned in MSVC C 2015
typedef enum {v0, v1, v2, v3} ENUMNAME;

你可以将它用作2位无符号索引,例如:

typedef struct {
  ENUMNAME i:2;
} STRUCTNAME;

在GCC ARM中尝试过,但不起作用。
此外,WinDbg显示STRUCTNAME.i为数字,而不是v0-v3。


那段代码不是重新定义了类型 ENUMNAME 吗? - U. Windl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接