Klocworkは、次の条件行で、「符号なしの値と0の比較は常に真である」と述べています。
#define MAX_VALUE 8589934592 //2^33
...
uint64_t val = get_val();
if (val >= MAX_VALUE)
{
return ERROR_INVALID_VALUE;
}
なんで?MAX_VALUEは0ではありません...
お知らせ下さい。
前もって感謝します。
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標準では、接尾辞のない10進リテラルは、int
の範囲内にある場合は型、 ;の範囲内にある場合int
は型になります。それ以外の場合、動作は定義されていません。gccのバージョンが2003標準に準拠している場合、動作の未定義は0と評価される可能性があり、これにより、発生している問題が説明されます。(しかし、整数リテラルが範囲外であるという警告が表示されると思います。そのような警告が表示されましたか?)long int
long int
8589934592
2011標準では、このようなリテラルのタイプは、、、int
またはlong
ですlong long
。(C ++2003にはありませんlong long
;C99から借用しました。)
(これ^
はビット単位のxor演算子であることに注意してください。C++には指数演算子がありません。コメントではそれほど重要ではありませんが2**33
、有効なC ++式ではない場合でも、より明確になる可能性があります。)
...
uint64_t val = get_val();
どのタイプがget_val()
返されますか?それは警告に影響を与えるべきではありませんが、知っておくと面白いでしょう。
if (val >= MAX_VALUE)
システムで64ビットの場合long
、これで問題ありません。long
が32ビットの場合、 /uint64_t
よりも幅が広い必要があります。これは、コンパイラがC++2003モードに準拠して動作していないことを意味します。long
unsigned long
次のプログラムでどのような出力が得られますか?
#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
。
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;
}