有没有办法让C / C ++预处理器或模板等将__FILE__和__LINE__以及其他一些外部输入(例如build-number)整理/散列到一个可以在日志中引用的短号中错误消息?
(当客户在错误报告中引用它时,意图是能够在需要时将其撤销(如果有损的候选人列表)。)
答案 0 :(得分:2)
您必须使用函数执行散列并从__LINE__
和__FILE__
创建代码,因为C预处理器无法执行此类复杂任务。
无论如何,您可以通过article获取灵感,看看不同的解决方案是否更适合您的情况。
答案 1 :(得分: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位。然而,Modulo 4096,带错误消息的行不太可能发生冲突。构建5位仍然没问题 - modulo 32意味着只有32个构建可以是未完成的并且错误仍然发生在同一行。)
答案 2 :(得分:0)
嗯......你可以使用类似的东西:
((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__ )
它不是完全独特的,但它可能适用于你想要的东西。可以将这些OR更改为+,这可能对某些事情更有效。
当然,如果你真的可以创建一个哈希码,你可能会想要这样做。
答案 3 :(得分: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;
}
答案 4 :(得分: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。然后,您可以非常轻松地将值与调试版本中的行/数/版本吐出相关联。
您需要包含版本号或内部版本号,因为这些错误位置可能随任何版本而改变。
如果无法重现代码路径,则效果不佳。
答案 5 :(得分:0)
__ FILE__是指向程序常量段的指针。如果你输出它和其他常量之间的差异,你应该得到一个独立于任何重定位等的结果:
extern const char g_DebugAnchor;
#define FILE_STR_OFFSET (__FILE__ - &g_DebugAnchor)
然后您可以报告,或者以某种方式将其与行号等组合.FILE_STR_OFFSET的中间位可能是最有趣的。