我正在重构一个库并试图摆脱许多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::NONE
,libother::UNKNOWN
)?
答案 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 int
或static_cast
。
答案 3 :(得分:0)
如果-1是合法值,那么这些数据应该是ssize_t
。
将-1转换为size_t
只会欺骗编译器,并对size_t
的其他正确值赋予特殊含义,尽管非常大。
如果您坚持使用最高值表示“无效”,请使用SIZE_MAX
代替-1。