1

我在目前正在处理的代码中发现了这一点,并认为这是我遇到的一些问题的原因。

在某处的标题中:

enum SpecificIndexes{
    //snip
    INVALID_INDEX = -1
};

然后稍后 - 初始化:

nextIndex = INVALID_INDEX;

并使用

if(nextIndex != INVALID_INDEX)
{
    //do stuff
}

调试代码,nextIndex 中的值不太有意义(它们非常大),我发现它被声明了:

unsigned int nextIndex;

因此,INVALID_INDEX 的初始设置使 unsigned int 下溢并将其设置为一个巨大的数字。我认为这是导致问题的原因,但仔细观察,测试

if(nextIndex != INVALID_INDEX)

行为正确,即当 nextIndex 为“大 +ve 值”时,它从未执行 if 的主体。

它是否正确?这是怎么回事?枚举值是否被隐式转换为与变量相同类型的无符号整数,因此以相同的方式包装?

4

5 回答 5

12

是的一切。它是有效代码,也是常用的库端 C++ 代码,在现代 C++ 中更是如此(当你第一次看到它时很奇怪,但它在现实中是一种非常常见的模式)。

然后枚举是有符号整数,但它们会隐式转换为无符号整数,现在这取决于您的编译器可能会发出警告,但它仍然非常常用,但是您应该显式转换以使维护者清楚。

于 2008-11-19T11:35:53.723 回答
2

根据枚举是否包含任何负值以及编译器的感觉,枚举可以用有符号或无符号整数类型表示。此处的示例包含负值,因此必须由有符号整数类型表示。

有符号和无符号类型之间的相等比较是安全的,通常会按照作者的意图进行 - 有符号值将首先转换为无符号,这样做的结果由 C++ 标准定义并且很直观(至少,一旦你知道目标类型。除非整数不是二进制补码。所以可能不是那么直观,但通常不会导致问题)。

订单比较更容易出错。例如:

SpecificIndexes value = INVALID_VALUE;
return (value >= 0);

返回 false,但是:

unsigned int value = INVALID_VALUE;
return (value >= 0);

返回真。有时作者不会欣赏这种差异,特别是如果“价值”的类型在使用时不是很明显。不过,编译器可能会对第二个示例发出警告,因为 (value >= 0) 是重言式。

于 2008-11-21T13:06:10.390 回答
1

事实上,当 -1 被分配给 nextValue 时,它​​被隐式地转换为它的等价无符号值。等价的无符号是具有相同按位表示的值(即 111111111111...,这是最大的无符号值)。

稍后,在比较语句中,发生了另一个隐式转换。

所以这现在有效,但将来可能会导致问题。混合有符号和无符号值绝不是一个好主意。

于 2008-11-19T11:35:03.833 回答
0

是的,我相信枚举已签名。改变

unsigned int nextIndex;

int nextIndex;

你的程序应该可以工作。

于 2008-11-19T11:47:01.873 回答
0

C++ 标准允许实现对枚举使用有符号类型,但不需要它。因此,您通常不能假设将负数放入枚举中是安全的。

于 2012-02-28T01:41:58.520 回答