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
)?
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).