質問

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

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

役に立ちましたか?

解決

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

とにかく、この記事からインスピレーションを得て、状況に応じて異なるソリューションが適している可能性があります。

他のヒント

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

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

完全に一意というわけではありませんが、希望どおりに機能する可能性があります。これらのORを+に変更できます。これは、いくつかの点でより適切に機能する可能性があります。

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

私のプロジェクトでシリアル値が必要で、 __ LINE __ __ FILE __ に特化したテンプレートを作成して取得しました。コンパイル時の出力を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;
}

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

#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をインクリメントします。その後、デバッグビルドによって値を行/番号/バージョンの吐き出しに相関させることができます。

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

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

__ FILE__は、プログラムの定数セグメントへのポインターです。その定数と他の定数の差を出力すると、再配置などに依存しない結果が得られます。

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

それを報告するか、何らかの方法で行番号などと組み合わせることができます。FILE_STR_OFFSETの中央のビットが最も興味深い可能性があります。

まあ、システムにクラッシュアドレスや機能を表示するのではなく、ユーザーに自分でメッセージを表示している場合、あなたが望むものを正確に表示することを妨げるものは何もありません。

例:

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を法として、エラーメッセージのある行は衝突する可能性は低い。 32を法とするのは、32ビルドのみが未解決であり、同じ行でエラーが発生することを意味します。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top