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

时间:2020-03-06 14:59:28  来源:igfitidea点击:

C ++枚举是签名的还是未签名的?通过扩展,可以安全地通过检查输入是否为<=最大值,并忽略> =最小值(假设我们从0开始并增加1)来验证输入吗?

解决方案

编译器可以确定枚举是有符号的还是无符号的。

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

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.

我们不应该依赖任何特定的表示形式。阅读以下链接。此外,该标准还说,由实现定义的是哪种整数类型用作枚举的基础类型,除非它的大小不得大于int,除非某些值不能适合int或者unsigned int。

简而言之:我们不能依赖已签名或者未签名的枚举。

我们不应该依赖于它们是已签名还是未签名。如果要使它们显式签名或者未签名,则可以使用以下命令:

enum X : signed int { ... };    // signed enum
enum Y : unsigned int { ... };  // unsigned enum

将来,随着C ++ 0x的出现,强类型枚举将可用并具有多个优点(例如类型安全,显式基础类型或者显式作用域)。这样,我们可以更好地确定类型的标志。

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

The underlying type of an enumeration
  is an integral type that can represent
  all the enumerator values defined in
  the enumeration. It is
  implementation-defined which integral
  type is used as the underlying type
  for an enumeration except that the
  underlying type shall not be larger
  than int unless the value of an
  enumerator cannot fit in an int or
  unsigned int.

简而言之,编译器可以选择(很明显,如果某些枚举值的值为负数,则会对其进行签名)。

我们不应该依赖于已签名或者未签名。根据标准,实现定义了哪种整数类型用作枚举的基础类型。但是,在大多数实现中,它是一个有符号整数。

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

enum X : signed int { ... };    // signed enum
enum Y : unsigned int { ... };  // unsigned enum

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

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.

除了其他人已经说过的关于有符号/无符号的内容之外,以下是该标准对枚举类型范围的说明:

7.2(6):"对于一个枚举,其中e(min)是最小的枚举数,而e(max)是最大的枚举,该枚举的值是在b(min)到b(max)范围内的基础类型的值),其中b(min)和b(max)分别是可以存储e(min)和e(max)的最小位字段的最小和最大值。可以定义一个未定义值的枚举通过其任何枚举​​器。"

因此,例如:

enum { A = 1, B = 4};

定义一个枚举类型,其中e(min)为1,e(max)为4. 如果基础类型为有符号int,则所需的最小位域为4位,如果实现中的int为二进制补码,则有效范围枚举是-8到7. 如果基础类型是无符号的,则它有3位,范围是0到7. 如果我们愿意,请查看编译器文档(例如,如果要将除枚举器以外的整数值强制转换为枚举类型,那么我们需要知道该值是否在枚举范围内(如果未指定结果枚举值)。

这些值是否为函数的有效输入,可能不同于它们是否为枚举类型的有效值。检查代码可能担心前者而不是后者,因此在此示例中至少应检查> = A和<= B。