C++ 枚举到 unsigned int 的比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/301622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:26:30  来源:igfitidea点击:

C++ enum to unsigned int comparison

c++enumscomparisonintegerunsigned

提问by xan

I found this in the code I'm working on at the moment and thought it was the cause of some problems I'm having.

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

In a header somewhere:

在某处的标题中:

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

Then later - initialization:

然后稍后 - 初始化:

nextIndex = INVALID_INDEX;

and use

并使用

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

Debugging the code, the values in nextIndex didn't quite make sence (they were very large), and I found that it was declared:

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

unsigned int nextIndex;

So, the initial setting to INVALID_INDEX was underflowing the unsigned int and setting it to a huge number. I assumed that was what was causing the problem, but looking more closely, the test

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

if(nextIndex != INVALID_INDEX)

Was behaving correctly, i.e, it never executed the body of the if when nextIndex was the "large +ve value".

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

Is this correct? How is this happening? Is the enum value being implicitly cast to an unsigned int of the same type as the variable, and hence being wrapped in the same way?

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

回答by Robert Gould

Yes to everything. It is valid code, it is also commonly used library-side C++ code, more so in modern C++ (it is strange when you see it the first time but its a very common pattern in reality).

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

Then enums are signed ints, but they get implicitly cast into unsigned ints, now this depending on your compiler might give a warning, but its still very commonly used, however you should explicitly cast to make it clear to maintainers.

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

回答by Steve Jessop

enums may be represented by signed or unsigned integral types according to whether they contain any negative values and what the compiler feels like. The example here contains a negative value and hence must be represented by a signed integral type.

枚举可以由有符号或无符号整数类型表示,具体取决于它们是否包含任何负值以及编译器的感觉。此处的示例包含负值,因此必须由有符号整数类型表示。

Equality comparison between signed and unsigned types is safe and usually does what the author intended - the signed value will be converted to unsigned first, and the result of doing that is defined by the C++ standard and is intuitive (at least, it is once you know the destination type. Except maybe if integers aren't two's complement. So maybe not that intuitive, but it doesn't normally cause problems).

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

Order comparison is more likely to result in errors. For example:

顺序比较更容易导致错误。例如:

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

returns false, but:

返回 false,但是:

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

returns true. Sometimes the author will not appreciate the difference, especially if the type of "value" isn't quite so obvious at the point of use. The compiler may well warn about the second example, though, because (value >= 0) is a tautology.

返回真。有时作者不会意识到差异,特别是如果“值”的类型在使用时不是很明显。不过,编译器可能会对第二个示例发出警告,因为 (value >= 0) 是同义反复。

回答by Gorpik

In fact, -1 is implicitly cast to its equivalente unsigned value when it is assigned to nextValue. The equivalente unsigned is the value with the same bitwise representation (which is 111111111111..., this is, the maximum unsigned value).

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

Later on, in the comparison statement, another implicit cast happens.

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

So this works right now, but may cause problem in the future. It is never a good idea to mix signed and unsigned values.

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

回答by Gorpik

Yes, I believe enums are signed. Change

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

unsigned int nextIndex;

to

int nextIndex;

and your program should work.

你的程序应该可以工作。

回答by Stu

The C++ standard allows an implementation to use a signed type for enums but does not require it. Therefore, you cannot in general assume that it is safe to put negative numbers into an enum.

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