C++ Klocwork抱怨无符号到零的比较总是正确的——为什么?

C++ Klocwork抱怨无符号到零的比较总是正确的——为什么?,c++,gcc,comparison,klocwork,C++,Gcc,Comparison,Klocwork,Klocwork在以下条件行中表示“无符号值与0的比较始终为真”: #define MAX_VALUE 8589934592 //2^33 ... uint64_t val = get_val(); if (val >= MAX_VALUE) { return ERROR_INVALID_VALUE; } 为什么??最大值不是0 请告知 提前感谢您。像Klocwork这样的工具有一定的“误报率”,通常为15%,但在某些情况下高达50%,实际上我的大部分工作是查看静态代码分析工具的输出

Klocwork在以下条件行中表示“无符号值与0的比较始终为真”:

#define MAX_VALUE 8589934592 //2^33
...
uint64_t val = get_val();
if (val >= MAX_VALUE)
{
  return ERROR_INVALID_VALUE;
}
为什么??最大值不是0

请告知


提前感谢您。

像Klocwork这样的工具有一定的“误报率”,通常为15%,但在某些情况下高达50%,实际上我的大部分工作是查看静态代码分析工具的输出,并确定它们报告的错误是否为误报(或是否存在误报)


长话短说,向我们展示get_val()的原型,告诉我它应该返回什么类型,我将了解它为什么报告该消息,以及它是否是FP。

没有大数字的替代解决方案(避免文字问题的大小)

文字可能是个问题,取决于你使用的C++版本和编译器如何选择对待它。

在2003年标准中,如果一个非固定十进制文本在
int
范围内,则它是
int
类型,如果它在
long int
范围内,则它是
long int
类型;否则,行为是未定义的。如果您的gcc版本符合2003标准,那么行为的不确定性可能表现为
8589934592
评估为0,这将解释您看到的问题。(但我希望得到一个关于整数文字超出范围的警告;您收到这样的警告了吗?)

在2011年标准中,此类文字可以是
int
long
long
类型。(C++2003没有
long
;它是从C99借来的。)

<>(注意,代码> >代码>是位异或运算;C++没有指数运算符。注释中没有任何关系,但是<代码> 2 ** 33 <代码>可能更清楚,即使这不是一个有效的C++表达式。
get\u val()
返回什么类型?这应该不会影响警告,但知道这一点会很有趣

if (val >= MAX_VALUE)
如果系统上的
long
为64位,则应该可以。如果<代码>长< /C++ >是32位,那么<代码> UTIN 64×T <代码>必须比“代码> >长/<代码>未签名的长更宽一些,这意味着您的编译器没有在符合C++ 2003模式下运行。

以下程序的输出是什么

#include <stdint.h>
#include <limits.h>
#include <iostream>
#include <ctime>

uint64_t get_val();

const char *type_name(int i) { return "int"; }
const char *type_name(long i) { return "long"; }
const char *type_name(unsigned long i) { return "unsigned long"; }
const char *type_name(long long i) { return "long long"; }
const char *type_name(unsigned long long i) { return "unsigned long long"; }

int main() {
    std::cout << "UINT_MAX   = " << UINT_MAX << "\n";
    std::cout << "ULONG_MAX  = " << ULONG_MAX << "\n";
    std::cout << "8589934592 = " << 8589934592 << "\n";
    std::cout << "8589934592 is of type " << type_name(8589934592) << "\n";

    uint64_t val = time(0);
    if (val >= 8589934592) {
        std::cout << "It's getting late!\n";
    }
}
#包括
#包括
#包括
#包括
uint64_u t get_val();
const char*type_name(int i){返回“int”;}
const char*type_name(long i){返回“long”;}
const char*type_name(无符号长i){返回“无符号长”;}
const char*type_name(long long i){返回“long long”;}
const char*type_name(unsigned long long i){返回“unsigned long”;}
int main(){

std::cout.Use
const uint64\u t MAX\u VALUE=2^33;
The
val>=MAX\u VALUE
对您来说是正确的?get\u val()的值是多少?
的声明是什么<代码> > INT/>代码。在大多数机器上,<代码> int <代码>不能是Big.j.f.SeBasTy: <代码> 2 ^ 33 /COD> > 35。<代码> ^ <代码>是位异或运算器。C++没有指数运算符。请尝试<代码>1@BoPersson:是,但在
val>中=MAX_VALUE
,因为
val
属于
uint64_t
类型,所以Trime:整型文字是任何类型的大到足以容纳它们的值。因为警告来自KLoWork,它更与C++标准的解释有关。这是一个很好的观点,但是,代码是不可移植的,像Klocwork这样的工具有权警告。@好。更新了我的答案以解决这种可能性。
...
uint64_t val = get_val();
if (val >= MAX_VALUE)
#include <stdint.h>
#include <limits.h>
#include <iostream>
#include <ctime>

uint64_t get_val();

const char *type_name(int i) { return "int"; }
const char *type_name(long i) { return "long"; }
const char *type_name(unsigned long i) { return "unsigned long"; }
const char *type_name(long long i) { return "long long"; }
const char *type_name(unsigned long long i) { return "unsigned long long"; }

int main() {
    std::cout << "UINT_MAX   = " << UINT_MAX << "\n";
    std::cout << "ULONG_MAX  = " << ULONG_MAX << "\n";
    std::cout << "8589934592 = " << 8589934592 << "\n";
    std::cout << "8589934592 is of type " << type_name(8589934592) << "\n";

    uint64_t val = time(0);
    if (val >= 8589934592) {
        std::cout << "It's getting late!\n";
    }
}