比较size_t变量与c ++代码中的-1(最大大小值)

时间:2014-08-02 10:43:55

标签: c++ comparison warnings unsigned-integer size-t

我正在重构一个库并试图摆脱许多gcc警告。这些警告的重要部分是签名/未签名比较,并与size_t的使用相关。该库适用于64位Linux系统。

程序员使用-1作为与std::string::npos类似的特殊值。 库中有很多地方代码如下:

class AnnotationBase
{
    public:
        size_t m_offset = -1;
        size_t m_length = -1;

}

...

AnnotationBase foo(const std::string& text, const AnnotationBase& annot)
{
    AnnotationBase newAnnot;

    // do some job with annotations and text
    ...

    if(newAnnot.m_offset == -1)
    {
        // do some other job
        ...
    }

    return newAnnot;
}

问题在于gcc在行if(newAnnot.m_offset == -1)上生成的警告,因为签名/未签名比较:

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

在没有警告的情况下,将C ++中的size_t变量与最大值(-1)进行比较的正确方法是什么?由于此表达式的复杂性和长度,这样做if(newAnnot.m_offset == std::numeric_limits<size_t>::max())非常不方便。

使用C风格的定义值SIZE_MAX是一种好方法,还是最好创建自己的常量,如namesapce libling { const NONE = std::numeric_limits<size_t>::max(); }(创建新常量会导致不同库和名称空间中的许多类似常量,如{ {1}},libling::NONElibother::UNKNOWN)?

4 个答案:

答案 0 :(得分:1)

您可以执行std::string所做的事情并定义static const size_t AnnotationBase::npos = -1。然后在比较中使用它作为约定。我不认为每个库的一个常量是一个问题,但是如果你想避免这种情况,你可以直接使用std::string::npos(这会使代码更加严格)。

答案 1 :(得分:1)

或者您可以使用this single header库并编写

if(sweet::equal(newAnnot.m_offset, -1))

指出这总是假的,因为size_t不能存储-1。但是比较不会产生任何警告,因为它正确且安全地处理不同的类型。此外,还有

甜::(以下| lessEqual | notEqual |大于| greaterEqual)

答案 2 :(得分:0)

-1的类型为int。在比较之前,您需要通过std::size_t将其转换为unsigned intstatic_cast

答案 3 :(得分:0)

如果-1是合法值,那么这些数据应该是ssize_t。 将-1转换为size_t只会欺骗编译器,并对size_t的其他正确值赋予特殊含义,尽管非常大。

如果您坚持使用最高值表示“无效”,请使用SIZE_MAX代替-1。