有没有办法让C / C ++预处理器或模板等将__FILE__和__LINE__以及其他一些外部输入(例如build-number)整理/散列到一个可以在日志中引用的短号中错误消息?

(当客户在错误报告中引用它时,意图是能够在需要时将其撤销(如果有损的候选人列表)。)

有帮助吗?

解决方案

由于C预处理器无法执行此类复杂任务,因此必须使用函数执行散列并从 __ LINE __ __ FILE __ 创建代码。

无论如何,您可以通过文章获取灵感,看看是否有不同的解决方案可以更好地适应您的情况。

其他提示

嗯......你可以使用类似的东西:

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

它不是完全独特的,但它可能适用于你想要的东西。可以将这些OR更改为+,这可能对某些事情更有效。

当然,如果你真的可以创建一个哈希码,你可能会想要这样做。

我需要在我的项目中使用序列值,并通过制作专门用于 __ 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的中间位可能是最有趣的。

好吧,如果您自己向用户显示消息(而不是系统显示崩溃地址或功能),那么没有任何东西可以阻止您显示您想要的内容。

例如:

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个构建可以是未完成的并且错误仍然发生在同一行。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top