我在我正在处理的代码中发现了这一点,并认为这是我遇到的一些问题的原因。
在某处的标题中:
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
答案 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 ++标准允许实现对枚举使用带符号的类型,但不需要它。因此,您通常不能假设将负数放入枚举中是安全的。