c ++枚举到unsigned int比较

时间:2008-11-19 11:28:01

标签: c++ enums comparison integer unsigned

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

在某处的标题中:

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的主体。

这是对的吗?这是怎么回事?枚举值是否被隐含地转换为与变量相同类型的unsigned int,因此以相同的方式包装?

干杯,

XAN

5 个答案:

答案 0 :(得分:11)

对所有事情都是肯定的。 它是有效的代码,它也是常用的库侧C ++代码,在现代C ++中更是如此(当你第一次看到它时很奇怪,但实际上它是一种非常常见的模式)。

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

答案 1 :(得分:2)

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

有符号和无符号类型之间的等式比较是安全的,通常做作者的意图 - 签名值将首先转换为无符号,并且这样做的结果由C ++标准定义并且直观(至少,它一旦你知道目的地类型。除非整数不是两个补码。所以也许不那么直观,但它通常不会引起问题。)

订单比较更有可能导致错误。例如:

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

返回false,但是:

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

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

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

unsigned int nextIndex;

int nextIndex;

并且您的计划应该有效。

答案 4 :(得分:0)

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