代码之家  ›  专栏  ›  技术社区  ›  Chen Gupta

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

  •  1
  • Chen Gupta  · 技术社区  · 10 年前

    我正在重构一个库,并试图消除许多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]"
    

    比较的正确方法是什么 大小(_t) C++中的变量具有最大值(-1)而没有警告?像这样做 if(newAnnot.m_offset == std::numeric_limits<size_t>::max()) 由于该表达式的复杂性和长度,非常不方便。

    使用C样式定义的值是一种好方法吗 SIZE_MAX 或者最好创建自己的常量 namesapce libling { const NONE = std::numeric_limits<size_t>::max(); } (创建新常量会在不同的库和命名空间中产生许多类似的常量,如 libling::NONE , libother::UNKNOWN , liblongnamesapcename::NOTHING )?

    4 回复  |  直到 10 年前
        1
  •  1
  •   eerorika    10 年前

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

        2
  •  1
  •   burner    10 年前

    或者你可以使用 this single header 库和写入

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

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

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

        3
  •  0
  •   Jarod42    10 年前

    -1 属于类型 int 。您需要将其转换为 std::size_t unsigned int 通过 static_cast 在你比较之前。

        4
  •  0
  •   Non-maskable Interrupt    10 年前

    这些数据应该是 ssize_t 相反,如果-1是合法值。 铸件-1至 size_t 只是欺骗编译器,并将特殊意义强加给其他适当的值,尽管非常大,因为 大小(_t) .

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