Klocwork抱怨unsigned to zero的比较总是正确的——为什么?
Klocwork complains about unsigned to zero comparison that is always true -- WHY?
Klocwork说" unsigned值与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中的一个bug(您应该报告)——或者您可能只需要用不同的选项调用它。(我自己从来没用过Klocwork)
您可以通过使用-std=c++0x
调用g++来解决(或至少绕过)这个问题。
像Klocwork这样的工具有一定的"误报"率,通常是15%,但在某些情况下高达50%,实际上我的工作的很大一部分是看静态代码分析工具的输出,并决定他们报告的错误是否为假阳性(或是否有假阴性)
长话短说,向我们展示get_val()的原型,并告诉我它应该返回什么类型,我将了解它为什么报告该消息以及它是否为FP。
不使用大数字的替代方案(避免文字大小问题)
const int MAX_VALUE_LOG2 = 33;
...
uint64_t val = get_val();
if ( (val >> MAX_MAX_VALUE_LOG2) > 0)
{
return ERROR_INVALID_VALUE;
}
- 为什么比较运算符如此快速
- 为什么:不同符号的整数比较只是偶尔发生?
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- 为什么组合的上限和下限比较的计算结果总是为 true?
- 为什么 Boost multi_index只修改第一个索引的键时对第二个索引进行比较?
- 为什么我的比较运算符不比较我的点长和双精度值?
- 为什么 std::stable_sort() 的比较函数的参数必须是设置常量?
- 为什么'Hello'与CPP中的'World'进行比较时被打印出来?
- 为什么在类或结构中传递自定义比较器函数?
- 浮点数比较为什么没有相等的函数
- 为什么 std::variant 找不到运算符<() 当与比较类不在同一命名空间中时
- 为什么sub_match和basic_string比较运算符使用额外的字符串副本实现?
- 为什么比较函数类型需要指定为模板参数?
- 为什么比较和交换操作同时存在免费函数和成员函数?
- 为什么比较运算符"=="返回"YES"即使两个向量不同?
- 为什么比较两次 char 变量比比较一次短变量更快
- 为什么比较两个字符串的结果遗漏了最后匹配的字符串
- 为什么比较方法不起作用?
- 为什么比较 constexpr 函数的两个参数不是静态断言的常量条件
- 为什么比较成员函数指针为NULL会产生警告?