func可以获得自称的lineno吗? (C / C ++)

时间:2010-04-16 09:24:08

标签: c++ c

我遇到了问题,因为以下代码会自行解释。

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]
但是,事实是 记录[Line:5]
记录[行:5]

毫不奇怪, LINE 在预处理阶段被替换为5.
我的问题是,如何设计日志功能以获得预期的结果?
谢谢!

3 个答案:

答案 0 :(得分:15)

你需要写一个宏:

#define LOG printf("Log [Line:%d]\n",__LINE__)

然后使用它:

int main() {
    LOG;
    LOG;
}

这是有效的,因为宏在其使用点展开,为__LINE__宏提供了正确的值。

答案 1 :(得分: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, ...)

答案 2 :(得分: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();
}