2

C/C++ プリプロセッサまたはテンプレートなどを取得して、__FILE__ と __LINE__、およびビルド番号などの他の外部入力を、ログまたはエラー メッセージで引用できる単一の短い番号にマングル/ハッシュする方法はありますか?

(意図は、顧客がバグレポートでそれを引用したときに、必要に応じてそれを元に戻すことができるようにすることです (損失がある場合は候補のリストに)。)

4

6 に答える 6

2

Cプリプロセッサはこのような複雑なタスクを実行できないため、関数を使用してハッシュを実行し、コードを作成する必要があります__LINE____FILE__

とにかく、この記事からインスピレーションを得て、別のソリューションが自分の状況により適しているかどうかを確認できます。

于 2008-09-26T22:22:26.773 に答える
0

ええと...あなたは次のようなものを使うことができます:

((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__ )

それは完全にユニークではありませんが、あなたが望むもののために働くかもしれません。それらのORを+に変更できます。これは、いくつかの点でうまく機能する可能性があります。

当然、実際にハッシュコードを作成できるのであれば、おそらくそれを実行したいと思うでしょう。

于 2008-09-26T22:25:03.757 に答える
0

私のプロジェクトではシリアル値が必要でしたが、それに特化したテンプレートを作成し__LINE____FILE__intを生成し、その入力に特化したテンプレートを生成して(stdoutへのコンパイル時出力として)行番号を生成しました。そのテンプレート。これらはコンパイラーを介して最初に収集され、次にコードファイルにダンプされ、プログラムが再度コンパイルされました。その時、テンプレートが使用された場所ごとに異なる番号が付けられました。

(Dで行われるため、C ++では不可能な場合があります)

template Serial(char[] file, int line)
{
    prgams(msg, 
    "template Serial(char[] file : \"~file~"\", int line : "~line.stringof~")"
      "{const int Serial = __LINE__;");
    const int Serial = -1;
}
于 2008-09-26T22:33:00.383 に答える
0

より簡単な解決策は、グローバルな静的な「エラー位置」変数を保持することです。

#ifdef DEBUG
#define trace_here(version) printf("[%d]%s:%d {%d}\n", version, __FILE__, __LINE__, errloc++);
#else
#define trace_here(version) printf("{%lu}\n", version<<16|errloc++);
#endif

または、printfなしで..トレースポイントを通過するたびにerrlocをインクリメントするだけです。次に、値をデバッグビルドによって吐き出された行/番号/バージョンに非常に簡単に関連付けることができます。

これらのエラーの場所はビルドによって変わる可能性があるため、バージョンまたはビルド番号を含める必要があります。

コードパスを再現できない場合はうまく機能しません。

于 2008-09-26T22:35:41.937 に答える
0

__FILE__ は、プログラムの定数セグメントへのポインターです。それと他の定数との差を出力すると、再配置などとは無関係の結果が得られるはずです。

extern const char g_DebugAnchor;
#define FILE_STR_OFFSET (__FILE__ - &g_DebugAnchor)

次に、それを報告するか、何らかの方法で行番号などと組み合わせることができます。FILE_STR_OFFSET の中間ビットは、おそらく最も興味深いものです。

于 2008-10-03T21:04:55.187 に答える
0

ユーザー自身にメッセージを表示する場合 (クラッシュ アドレスや機能をシステムに表示させるのではなく)、必要なものを正確に表示することを妨げるものは何もありません。

例えば:

typedef union ErrorCode {
    struct {
        unsigned int file: 15;
        unsigned int line: 12; /* Better than 5 bits, still not great
                                  Thanks commenters!! */
        unsigned int build: 5;
    } bits;
    unsigned int code;
} ErrorCode;

unsigned int buildErrorCodes(const char *file, int line, int build)
{
    ErrorCode code;
    code.bits.line=line   & ((1<<12) - 1);
    code.bits.build=build & ((1<< 5) - 1);
    code.bits.file=some_hash_function(file) & ((1<<15) - 1);

    return code.code;
}

あなたはそれを次のように使用します

buildErrorCodes(__FILE__, __LINE__, BUILD_CODE) 

そしてそれを16進数で出力します。デコードするのはそれほど難しくありません...

(編集済み -- コメンターは正しいです。行番号に 5 ビットを指定するのは気が狂っていたに違いありません。モジュロ 4096 ですが、エラー メッセージのある行が衝突する可能性は低いです。ビルドの 5 ビットはまだ問題ありません - モジュロ 32 は意味します32 のビルドのみが未解決であり、同じ行でエラーが引き続き発生する可能性があります。)

于 2008-09-26T22:20:10.943 に答える