Comparison size_t variable with -1 (maximum size value) in c++ code

无人久伴 提交于 2020-06-01 04:14:50

问题


I'm refactoring a library and trying to get rid of many gcc warnings. The big part of these warning are about signed / unsigned comparison and are related to the usage of size_t. The library works on 64 bit Linux systems.

A programmer used -1 as the special value similar to std::string::npos. There are many places in the library where code looks like this:

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;
}

The problem lies in the warning that gcc generates on the line if(newAnnot.m_offset == -1) because of a signed / unsigned comparison:

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

What is the proper way to compare size_t variable in C++ with the maximum value (-1) without warning? Doing this like if(newAnnot.m_offset == std::numeric_limits<size_t>::max()) is very inconvenient due to complexity and length of this expression.

Is it a good way to use C-style defined value SIZE_MAX or it is better to create own constant like namesapce libling { const NONE = std::numeric_limits<size_t>::max(); } (Creating new constant leads to many similar constants in different libraries and namespaces like libling::NONE, libother::UNKNOWN, liblongnamesapcename::NOTHING)?


回答1:


You could do what std::string does and define a static const size_t AnnotationBase::npos = -1. Then use that in comparisons as a convention. I wouldn't consider one constant per library a problem, but if you want to avoid that, you can use std::string::npos directly (that makes the code more rigid though).




回答2:


or you can use this single header library and write

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

as pointed out this is always false as size_t can't store a -1. But the comparison will not create any warnings as it handles different types correctly and safely. Additionally, there is

sweet::(less|lessEqual|notEqual|greater|greaterEqual)




回答3:


-1 is of type int. You need to convert it to std::size_t or unsigned int via a static_cast before you compare it.




回答4:


Those data should be ssize_t instead if -1 is a legal value. Casting -1 to size_t is just cheating the compiler and impose special meaning to the otherwise proper value, although very large, for size_t.

If you insist to use the highest value to mean "invalid", use SIZE_MAX instead of -1.



来源:https://stackoverflow.com/questions/25094159/comparison-size-t-variable-with-1-maximum-size-value-in-c-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!