2008-09-26 40 views
2

有沒有辦法讓C/C++預處理器或模板等將__FILE__和__LINE__以及其他一些外部輸入(比如內部版本號)打散/散列成一個可以在日誌或錯誤中引用的短數字消息?在代碼中引用__FILE__和__LINE__以引用?

(如果它有損)在需要時客戶報價它在一個bug報告時,有意將能夠扭轉它(候選人名單。)

+1

你認爲用戶在引用文件+行時會遇到麻煩,但是能夠給你一個沒有轉置數字的散列? – Shog9 2008-09-26 22:06:14

+1

最有可能的是隱藏客戶有關問題出現的信息,但這個數字應該使其對技術支持人員有用。我對處理可能的數字數量所需的數據庫大小存在疑慮。 – 2008-10-19 07:02:02

回答

2

您必須使用函數來執行散列並且由於C預處理器無法執行如此複雜的任務,因此需要創建一個來自__LINE____FILE__的代碼。

無論如何,你可以從這個article獲取靈感,看看不同的解決方案是否可以更好地適應你的情況。

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) 

,並以十六進制輸出。它不會很難解碼...

(編輯 - 評論者是正確的,我必須堅持指定5位的行號模數4096,但是,帶有錯誤信息的行aren' t可能會發生衝突,構建5位仍然很好 - 模32表示只有32個構建可以出色,並且錯誤仍然發生在同一行。)

+0

您必須爲__LINE__準備一些嚴重短的源文件以適應5位。 – 2008-09-26 22:24:26

0

嗯......你可以使用類似:

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

它不會是完全獨一無二的,但它可能爲你想要的工作。可以將這些OR更改爲+,這對於某些事情可能會更好。

當然,如果你真的可以創建一個哈希碼,你可能會想這樣做。

0

我需要在我的一個項目中使用串行valuse,並通過製作一個專門用於__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; 
} 
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。然後,您可以很容易地將該值與調試版本的線/編號/版本關聯起來。

您需要包含版本或內部版本號,因爲這些錯誤位置可能隨任何版本而改變。

如果無法重現代碼路徑,則效果不佳。

0

__FILE__是指向程序的常量段的指針。如果輸出和其他一些常量你應該得到一個結果,這是獨立於任何搬遷等之間的區別:

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

然後,您可以報告,或以某種方式與行號等結合起來FILE_STR_OFFSET的中間位可能是最有趣的。