警告:有符号和无符号整数表达式之间的比较[-Wsign-compare]

时间:2015-06-18 10:39:14

标签: c++

警告在下面一行

for(int nPort = 0 ; nPort< (sizeof(nArrOverloadParams)/sizeof(int)) && nRetVal 
                    == RET_SUCCESS_VALUE ;nPort++)

1 个答案:

答案 0 :(得分:0)

警告表示原则的比较可能失败。带符号的值是(1)提升为无符号类型。如果它是否定的(编译器不知道它不是,没有广泛的分析)那么促销到无符号会产生一个非常大的值。

结果是你保证

std::string( "Blah" ).length() < -5

这是非常愚蠢的 - 这是大小值的类型选择的结果,一旦有意义,但目前是非常不理想的(但由于需要兼容性而无法改变)。

根据经验,

是个好主意
  • 对数字使用签名类型,但

  • 使用无符号类型进行位级操作。

E.g。您可以使用ptrdiff_t(指针差异表达式的结果类型)作为size_t的签名版本。

然后,您可以为数组表示签名大小函数,例如

#include <stddef.h>

namespace cppx {
    using Size = ptrdiff_t;

    template< class Item, Size n >
    auto n_items( Item (&)[n] )
        -> Size
    { return n; }
}

然后循环的相关部分变为

using cppx::n_items;

int overloadedParams[77];
for( int port = 0 ; port< n_items( overloadedParams ); port++ )

另一种方法是使用基于范围的循环,绕过整个问题:

for( int param : overloadedParams )

如果循环体的逻辑需要索引,则可以添加计数器。

循环的行为是根据用std::beginstd::end表示的等效代码定义的。

历史。据我所知,Dietmar Kuhl认为函数三元组beginendn_items实际上很有用(它是签名大小编程的必要支持),尽管不是那样的第三个函数的名称。 C ++ 11标准添加了std::beginstd::end,但没有std::n_itemsstd::extent是一个非常不同的野兽)。

1)在标准中,此转换是C ++14§5/ 10定义的“常规算术转换”的一部分。 功能