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
#define MAX_VALUE 8589934592 //2^33

使用しているC++のバージョンと、コンパイラがそれをどのように処理するかによっては、そのリテラルが問題になる可能性があります。

2003標準では、接尾辞のない10進リテラルは、intの範囲内にある場合は型、 ;の範囲内にある場合intは型になります。それ以外の場合、動作は定義されていません。gccのバージョンが2003標準に準拠している場合、動作の未定義は0と評価される可能性があり、これにより、発生している問題が説明されます。(しかし、整数リテラルが範囲外であるという警告が表示されると思います。そのような警告が表示されましたか?)long intlong int8589934592

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モードに準拠して動作していないことを意味します。longunsigned 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

于 2011-11-07T10:46:28.703 に答える
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 に答える