问题
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