1

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

#define MAX_VALUE 8589934592 //2^33
...
uint64_t val = get_val();
if (val >= MAX_VALUE)
{
  return ERROR_INVALID_VALUE;
}

为什么?MAX_VALUE 不是 0...

请指教。

先感谢您。

4

3 回答 3

0

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

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

于 2011-11-06T12:45:44.200 回答
0

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

const int MAX_VALUE_LOG2 = 33;
...
uint64_t val = get_val();
if ( (val >> MAX_MAX_VALUE_LOG2) > 0)
{
  return ERROR_INVALID_VALUE;
}
于 2011-11-07T09:39:34.913 回答
0
#define MAX_VALUE 8589934592 //2^33

该文字可能是一个问题,具体取决于您使用的 C++ 版本以及编译器选择如何处理它。

在 2003 年标准中,无后缀的十进制文字int如果在 的范围内,则为类型,如果在 ; 的范围内,则为int类型。否则,行为未定义。如果您的 gcc 版本符合 2003 标准,则行为的不确定性可能会表现为评估为 0,这可以解释您所看到的问题。(但我希望收到有关整数文字超出范围的警告;您收到这样的警告吗?)long intlong int8589934592

在 2011 标准中,这样的文字可以是intlonglong long. (C++ 2003 没有long long;它是从 C99 借来的。)

(注意这^是按位异或运算符;C++ 没有指数运算符。这在注释中并不重要,但2**33可能更清楚,即使这也不是有效的 C++ 表达式。)

...
uint64_t val = get_val();

返回什么类型get_val()?这不应该影响警告,但知道会很有趣。

if (val >= MAX_VALUE)

如果long您的系统上是 64 位,那么这应该没问题。如果long是 32 位,则uint64_t必须比long/更宽unsigned long——这意味着您的编译器未在符合 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";
    }
}

Klocwork 在比较时会给您什么警告(如果有的话)?如果 Klockwork 给您一个与程序输出不一致的警告,这可能是 Klocwork 中的一个错误(您应该报告)——或者您可能只需要使用不同的选项来调用它。(我自己从未使用过 Klocwork。)

您可以通过调用 g++ 来解决(或至少解决)问题-std=c++0x

于 2011-11-07T10:46:28.703 回答