C++枚举是签名还是未签名?

Mat*_*att 105 c++ enums

C++枚举是签名还是未签名?通过扩展,通过检查输入<=您的最大值来验证输入是安全的,并且省去> =您的最小值(假设您从0开始并递增1)?

Mic*_*urr 98

我们来看看源头.这是C++ 03标准(ISO/IEC 14882:2003)文档在7.2-5(枚举声明)中所说的内容:

枚举的基础类型是一个整数类型,可以表示枚举中定义的所有枚举器值.它是实现定义的,其中整数类型用作枚举的基础类型,除了基础类型不应大于int,除非枚举器的值不能适合int或unsigned int.

简而言之,您的编译器可以选择(显然,如果您的某些枚举值有负数,它将被签名).


zvr*_*rba 59

您不应该依赖任何特定的表示.阅读以下链接.此外,标准表示它是实现定义的,哪个整数类型用作枚举的基础类型,除了它不应大于int,除非某些值不能适合int或unsigned int.

简而言之:你不能依赖于签名或未签名的枚举.

  • [Michael Burr的答案](http://stackoverflow.com/a/159308/594137)(引用标准)实际上暗示你*可以*依赖它被签名如果你将枚举值定义为负值,因为类型是能够"表示枚举中定义的所有枚举器值". (27认同)

Ada*_*eld 22

您不应该依赖它们签名或未签名.如果要使它们明确签名或未签名,可以使用以下命令:

enum X : signed int { ... };    // signed enum
enum Y : unsigned int { ... };  // unsigned enum
Run Code Online (Sandbox Code Playgroud)

  • 仅在未来的C++ 0x标准中. (11认同)
  • @dalle Microsoft compilator也允许键入的枚举http://msdn.microsoft.com/en-us/library/2dzy4k6e(v=vs.80).aspx (3认同)

Mat*_*att 15

您不应该依赖签名或未签名.根据标准,它是实现定义的,其中整数类型用作枚举的基础类型.但是,在大多数实现中,它是有符号整数.

在C++ 0x中,将添加强类型枚举,这将允许您指定枚举的类型,例如:

enum X : signed int { ... };    // signed enum
enum Y : unsigned int { ... };  // unsigned enum
Run Code Online (Sandbox Code Playgroud)

但是,即使是现在,也可以通过将枚举用作变量或参数类型来实现一些简单的验证:

enum Fruit { Apple, Banana };

enum Fruit fruitVariable = Banana;  // Okay, Banana is a member of the Fruit enum
fruitVariable = 1;  // Error, 1 is not a member of enum Fruit
                    // even though it has the same value as banana.
Run Code Online (Sandbox Code Playgroud)


Cri*_*omo 5

编译器可以决定枚举是已签名还是未签名.

验证枚举的另一种方法是使用枚举本身作为变量类型.例如:

enum Fruit
{
    Apple = 0,
    Banana,
    Pineapple,
    Orange,
    Kumquat
};

enum Fruit fruitVariable = Banana;  // Okay, Banana is a member of the Fruit enum
fruitVariable = 1;  // Error, 1 is not a member of enum Fruit even though it has the same value as banana.
Run Code Online (Sandbox Code Playgroud)


Kri*_*ler 5

将来,在 C++0x 中,强类型枚举将可用,并且具有多种优点(例如类型安全、显式基础类型或显式作用域)。这样您就可以更好地确定该类型的符号。


Jav*_*Man 5

即使是一些旧的答案也有44个赞成票,我倾向于不同意所有这些答案.简而言之,我认为我们不应该关心underlying type枚举.

首先,C++ 03 Enum类型是一个独特的类型,没有符号概念.从C++ 03标准开始dcl.enum

7.2 Enumeration declarations 
5 Each enumeration defines a type that is different from all other types....
Run Code Online (Sandbox Code Playgroud)

因此,当我们讨论枚举类型的符号时,比如在使用<运算符比较2个枚举操作数时,我们实际上是在讨论将枚举类型隐式转换为某种整数类型.重要的是这种整体类型的标志.当将枚举转换为整数类型时,此语句适用:

9 The value of an enumerator or an object of an enumeration type is converted to an integer by integral promotion (4.5).
Run Code Online (Sandbox Code Playgroud)

而且,显然,枚举的基本类型与积分促销无关.由于标准定义了Integral Promotion,如下所示:

4.5 Integral promotions conv.prom
.. An rvalue of an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of the enumeration
(i.e. the values in the range bmin to bmax as described in 7.2: int, unsigned int, long, or unsigned long.
Run Code Online (Sandbox Code Playgroud)

因此,枚举类型是否成为signed intunsigned int取决于是否signed int可以包含定义的枚举数的所有值,而不是枚举的基础类型.

请参阅我的相关问题 转换为积分类型后C++枚举类型的符号不正确