【问题标题】:Automatically inserting filename & line number in logging statements of a C program在 C 程序的日志记录语句中自动插入文件名和行号
【发布时间】:2014-05-28 15:50:26
【问题描述】:

我正在用 C 为嵌入式 ARM 处理器编写程序。我想在日志记录语句中查看源文件名和行号。

由于编译后的代码不知道行号和源文件,我正在寻找在编译过程之前/期间自动插入的方法。

是否有任何标准工具或编译器功能可供我使用?

我正在使用 GCC。

例如:

这就是我要在源文件中写的内容:

log("<#filename#> <#linenumber#> : Hello World");

这是实际编译的内容:

log("Foobar.c 225 : Hello World");

【问题讨论】:

    标签: c debugging gcc arm c-preprocessor


    【解决方案1】:

    通常你会这样做:

    // logging function
    void log(const char * file, const int line, const char *msg)
    {
        fprintf(stderr, "%s:%d: %s\n", file, line, msg);
    }
    
    // logging macro - passes __FILE__ and __LINE__ to logging function
    #define LOG(msg) do { log(__FILE__, __LINE__, msg) } while (0)
    

    那么当你想记录一些东西时:

    LOG("We made it to this point!");
    

    然后会生成一条日志消息,例如:

    foo.c:42: We made it to this point!
    

    【讨论】:

    • 谢谢。但是while(0)的目的是什么?
    • do { ... } while(0) 只是编写宏的规范方法,可以像调用函数一样调用它而不会引起问题,例如当放置在else 之前时。在这种情况下它实际上是多余的,因为只有一条语句,但这是一个好习惯,以防您以后想向宏添加更多代码。
    • 值得一提,即使这个问题是针对 GCC 的:Visual Studio 喜欢 file(line) : message 的格式。 msdn.microsoft.com/en-us/library/yxkt8b26.aspx
    • @MooingDuck:是的,微软总是喜欢做与文明世界不同的事情。 ;-) 我认为 OP 特别提到他们正在使用 gcc,但显然上述技术可以根据您选择的平台/编译器进行定制。
    【解决方案2】:

    作为预处理器的一部分,有一组标准的预定义宏:https://gcc.gnu.org/onlinedocs/gcc-4.9.0/cpp/Standard-Predefined-Macros.html

    您要使用的宏是__FILE____LINE__,它们是文件名和行号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      • 2012-08-18
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      相关资源
      最近更新 更多