有沒有辦法讓C/C++預處理器或模板等將__FILE__和__LINE__以及其他一些外部輸入(比如內部版本號)打散/散列成一個可以在日誌或錯誤中引用的短數字消息?在代碼中引用__FILE__和__LINE__以引用?
(如果它有損)在需要時客戶報價它在一個bug報告時,有意將能夠扭轉它(候選人名單。)
有沒有辦法讓C/C++預處理器或模板等將__FILE__和__LINE__以及其他一些外部輸入(比如內部版本號)打散/散列成一個可以在日誌或錯誤中引用的短數字消息?在代碼中引用__FILE__和__LINE__以引用?
(如果它有損)在需要時客戶報價它在一個bug報告時,有意將能夠扭轉它(候選人名單。)
您必須使用函數來執行散列並且由於C預處理器無法執行如此複雜的任務,因此需要創建一個來自__LINE__
和__FILE__
的代碼。
無論如何,你可以從這個article獲取靈感,看看不同的解決方案是否可以更好地適應你的情況。
好吧,如果你正在顯示向用戶發送消息(而不是由系統顯示崩潰地址或功能),因此沒有什麼可以阻止您準確顯示您想要的內容。
例如:
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個構建可以出色,並且錯誤仍然發生在同一行。)
您必須爲__LINE__準備一些嚴重短的源文件以適應5位。 – 2008-09-26 22:24:26
嗯......你可以使用類似:
((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__)
它不會是完全獨一無二的,但它可能爲你想要的工作。可以將這些OR更改爲+,這對於某些事情可能會更好。
當然,如果你真的可以創建一個哈希碼,你可能會想這樣做。
我需要在我的一個項目中使用串行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;
}
一個簡單的解決辦法是保持全球靜態「錯誤的位置」變量。
#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的中間位可能是最有趣的。
你認爲用戶在引用文件+行時會遇到麻煩,但是能夠給你一個沒有轉置數字的散列? – Shog9 2008-09-26 22:06:14
最有可能的是隱藏客戶有關問題出現的信息,但這個數字應該使其對技術支持人員有用。我對處理可能的數字數量所需的數據庫大小存在疑慮。 – 2008-10-19 07:02:02