“有符号和无符号整型表达式之间的比较”真的会导致错误吗?

时间:2021-12-02 12:05:11

Often an object I use will have (signed) int parameters (e.g. int iSize) which eventually store how large something should be. At the same time, I will often initialize them to -1 to signify that the object (etc) hasn't been setup / hasn't been filled / isn't ready for use.

我使用的对象通常会有(带符号的)int参数(例如,int iSize),这些参数最终会存储某个对象的大小。与此同时,我通常会将它们初始化为-1来表示对象(等等)没有设置/没有被填充/还没有准备好使用。

I often end up with the warning comparison between signed and unsigned integer, when I do something like if( iSize >= someVector.size() ) { ... }.

当我执行if(iSize >= somevec .size() {}。

Thus, I nominally don't want to be using an unsigned int. Are there any situations where this will lead to an error or unexpected behavior?

因此,名义上我不想使用无符号int类型。是否存在这种情况会导致错误或意外行为?

If not: what is the best way to handle this? If I use the compiler flag -Wno-sign-compare I could (hypothetically) miss a situation in which I should be using an unsigned int (or something like that). So should I just use a cast when comparing with an unsigned int--e.g. if( iSize >= (int)someVector.size() ) { ... } ?

如果不是:最好的处理方法是什么?如果我使用编译器标志-Wno-sign-compare,我(假设)可能会错过一个我应该使用无符号int(或类似的东西)的情况。所以我应该在与无符号int(无符号int)进行比较时使用cast吗?if(iSize >= (int) somevec .size()) {} ?

1 个解决方案

#1


5  

Yes, there are, and very subtle ones. If you are curious, you can check this interesting presentation by Stephan T. Lavavej about arithmetic conversion and a bug in Microsoft's implementation of STL which was caused just by signed vs unsigned comparison.

是的,有,而且非常微妙。如果你很好奇,你可以看看Stephan T. Lavavej关于算术转换的有趣的介绍,以及微软的STL实现中的一个bug,这是由签名vs无符号比较引起的。

In general, the problem is due to the fact that because of complement 2 arithmetic, a very small negative integral value has the same bit representation as a very big unsigned integral value (e.g. -1 = 0xFFFF = 65535).

一般来说,问题是由于补集2算法,一个很小的负整数值与一个很大的无符号整数值(例如-1 = 0xFFFF = 65535)具有相同的位表示。

In the specific case of checking size(), why not using type size_t for iSize in the first place? Unsigned values just give you greater expressivity, use it.

在检查大小()的特定情况下,为什么不首先使用类型size_t来表示iSize ?无符号值只会给你更强的表达能力,使用它。

And if you do not want to declare iSize as size_t, just make it clear by using an explicit cast that you are aware of the nature of this comparison. The compiler is trying to do you a favor with those warnings and, as you correctly wrote, there might be situations where ignoring them would cause you a very bad headache.

如果您不希望将iSize声明为size_t,只需使用显式强制转换说明您了解这种比较的本质。编译器试图帮你做这些警告,正如你正确地写的那样,可能有些情况下忽略它们会让你头疼得很厉害。

Thus, if iSize is sometimes negative (and should be evaluated as less than all unsigned int values of size()), use the idiom: if ((iSize < 0) || ((unsigned)iSize < somevector.size())) ...

因此,如果iSize有时是负的(并且应该被评估为小于size()的所有无符号int值),请使用这个习惯用法:if ((iSize < 0) ||(((无符号)iSize < somevec .size())))……

#1


5  

Yes, there are, and very subtle ones. If you are curious, you can check this interesting presentation by Stephan T. Lavavej about arithmetic conversion and a bug in Microsoft's implementation of STL which was caused just by signed vs unsigned comparison.

是的,有,而且非常微妙。如果你很好奇,你可以看看Stephan T. Lavavej关于算术转换的有趣的介绍,以及微软的STL实现中的一个bug,这是由签名vs无符号比较引起的。

In general, the problem is due to the fact that because of complement 2 arithmetic, a very small negative integral value has the same bit representation as a very big unsigned integral value (e.g. -1 = 0xFFFF = 65535).

一般来说,问题是由于补集2算法,一个很小的负整数值与一个很大的无符号整数值(例如-1 = 0xFFFF = 65535)具有相同的位表示。

In the specific case of checking size(), why not using type size_t for iSize in the first place? Unsigned values just give you greater expressivity, use it.

在检查大小()的特定情况下,为什么不首先使用类型size_t来表示iSize ?无符号值只会给你更强的表达能力,使用它。

And if you do not want to declare iSize as size_t, just make it clear by using an explicit cast that you are aware of the nature of this comparison. The compiler is trying to do you a favor with those warnings and, as you correctly wrote, there might be situations where ignoring them would cause you a very bad headache.

如果您不希望将iSize声明为size_t,只需使用显式强制转换说明您了解这种比较的本质。编译器试图帮你做这些警告,正如你正确地写的那样,可能有些情况下忽略它们会让你头疼得很厉害。

Thus, if iSize is sometimes negative (and should be evaluated as less than all unsigned int values of size()), use the idiom: if ((iSize < 0) || ((unsigned)iSize < somevector.size())) ...

因此,如果iSize有时是负的(并且应该被评估为小于size()的所有无符号int值),请使用这个习惯用法:if ((iSize < 0) ||(((无符号)iSize < somevec .size())))……