繁体   English   中英

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

[英]warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

以下行中的警告

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

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

结果是你可以保证

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

这简直太愚蠢了——这是为曾经有意义的大小值选择类型的结果,但目前这是非常次优的(但由于需要兼容性而无法更改)。

因此,根据经验,这是一个好主意

  • 对数字使用有符号类型,但

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

例如,您可以使用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 定义的“常用算术转换”的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM