Klocwork 在以下条件行中表示“无符号值与 0 的比较始终为真”:
#define MAX_VALUE 8589934592 //2^33
...
uint64_t val = get_val();
if (val >= MAX_VALUE)
{
return ERROR_INVALID_VALUE;
}
为什么? MAX_VALUE 不是 0...
请指教。
提前谢谢你。
最佳答案
#define MAX_VALUE 8589934592 //2^33
该文字可能是个问题,具体取决于您使用的 C++ 版本以及您的编译器选择如何处理它。
在 2003 标准中,如果一个无后缀的十进制文字在 int
范围内,则它是 int
类型,或者是 long int
类型如果在long int
范围内;否则,行为未定义。如果您的 gcc 版本符合 2003 标准,则行为的未定义性可能表现为 8589934592
评估为 0,这可以解释您所看到的问题。 (但我希望收到有关整数文字超出范围的警告;您收到这样的警告了吗?)
在 2011 标准中,这样的文字可以是 int
、long
或 long 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。)
您可以通过使用 -std=c++0x
调用 g++ 来解决(或至少解决)问题。
关于c++ - Klocwork 提示无符号与零的比较总是正确的——为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8026797/