能否在C/C++中使用func函数获取调用它的行号?

6

我有一个问题,如下代码所述。

1  #include<stdlib.h>
2  #include<stdio.h>
3  void log()
4  {
5         printf("Log [Line:%d]\n",__LINE__);
6  }
7  int main()
8  {
9         log();
10        log();
11 }

期望的结果是:
日志[行:9]
日志[行:10]
但事实是
日志[行:5]
日志[行:5]
毫不奇怪,LINE已在预处理阶段替换为5。
我的问题是,如何设计日志函数以获得期望的结果?
谢谢!
3个回答

15
你需要编写一个宏:
#define LOG printf("Log [Line:%d]\n",__LINE__)

然后使用它:

int main() {
    LOG;
    LOG;
}

这能够正常工作是因为宏在使用时会被展开,从而给__LINE__宏提供正确的值。

在C++中,您也可以使用内联函数。 - waffleman
3
不行 - 宏展开(__LINE__宏)在编译器看到代码之前发生。 - anon
一个内联函数不起作用- __LINE__ 是一个预处理器宏,在预处理期间进行替换,而不是在函数内联期间进行替换。(编辑:被忍者打败了) - AshleysBrain

4

宏可以通过将__LINE__作为参数传递给调用的函数来克服这个问题。

另一种可能是相辅相成的方法是将一些上下文作为参数传递给函数,其中默认值表示“使用行号”。以下代码片段演示了使用该模式进行错误处理:

int read_byte(FILE* f,int line=0) {
  int ret = fgetc(f);
  if(-1 == ret)
     throw (line? line: __LINE__);
  return ret;
}

int read_uint16(FILE* f,int line=0) {
  int hi = read_byte(f,(line? line: __LINE__));
  int lo = read_byte(f,(line? line: __LINE__));
  return (hi<<8)|lo;
}

int main() {
  ...
  try {
    int i = read_uint16(f,__LINE__);
  } catch(int line) {
    fprintf(stderr,"Error at line %d\n",line);
  }
  ...
}

最后,这一切都像是想要从C/C++代码中获取堆栈跟踪(特别是在错误处理情况下)。请查看VALGRIND_PRINTF_BACKTRACE(format, ...)


1
你可以稍微修改你现有的函数,然后将其包装在一个宏中:
#include<stdlib.h>
#include<stdio.h>

#define log() real_log(__LINE__)

void real_log(int line)
{
       printf("Log [Line:%d]\n", line);
}

int main()
{
       log();
       log();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接