为什么要在C ++中使用__LINE__宏

时间:2009-11-12 01:27:54

标签: c++

我想弄清楚人们如何在工作中使用__LINE__宏。你们是如何使用它的?

8 个答案:

答案 0 :(得分:16)

您可以使用__LINE____FILE__来报告源代码中出现问题的位置。

例如,考虑assert()宏 - 来自C99标准的这个措辞,但C ++是相似的,除了它没有提到__func__

  

执行时,如果表达式(具有标量类型)为false(即,   比较等于0),断言宏写入有关特定呼叫的信息   失败(包括参数的文本,源文件的名称,源代码行   number和封闭函数的名称 - 后者分别是值的值   预处理宏__FILE____LINE__以及标识符   __func__)以实现定义的格式标准错误流。

#define assert(x) (void)(((x)==0)?_Assert(#x,__FILE__,__LINE__,__func__):0)

答案 1 :(得分:7)

一个更简单的例子,这是我在所有其他形式的调试失败时偶尔使用的宏:

#define GOT_HERE std::cout << "At " __FILE__ ":" << __LINE__ << std::endl

然后,当你的代码神秘地崩溃并用它取下设备时,你至少可以将这个宏自由地放到源中,希望它能让你缩小发生崩溃的地方(以及经过多少次重复) )。在实践中,您可能不会写入std :: cout,而是使用平台上可用的最低级别,最可靠的字符输出。

答案 2 :(得分:5)

我为malloc编写了一个包装器:

#if DEBUG

#define malloc(s) debugging_malloc(s, __FILE__, __LINE__)
#define free(p) debugging_free(p)

// Also, calloc(), strdup(), realloc() should be wrapped.
#endif // DEBUG

在包装器中,将根据文件和行号来跟踪分配。程序退出时,实用程序功能会输出任何不同块的列表。

如果您正在使用gcc,它还会为您提供__FUNCTION__,这非常好。兼容C99的编译器也有__func__,同样方便。

答案 3 :(得分:4)

到目前为止,大多数答案都涉及某种调试代码。 __LINE__(以及可能__FILE__)的另一个用途是使宏能够在每次调用时生成唯一标识符。这个implementation of coroutines in C使用这些宏为case语句生成标签,因此它可以跳转到你调用yield的最后一行。

答案 4 :(得分:1)

就像这样:

$ cat line.cc
#include <iostream>

int main(void) {
  std::cout << "Hello, world from " << __LINE__ << std::endl;
  return 0;
}
$ g++ -o line line.cc
$ ./line
Hello, world from 4
$

答案 5 :(得分:0)

if (something truly impossible has happened) {
   fprintf(stderr, "Value of PI less than 3 detected at %s line %d\n", __FILE__, __LINE__);
}

在CPP宏中检测无法忍受的条件尤其方便。

答案 6 :(得分:0)

它实际上仅用于调试/记录目的。我很少使用它,因为我倾向于更频繁地依赖像gdb这样的调试器。

但是在输出调试信息时总是可以使用它。

void dosomething(Object* o)
{
  if (!o) {
    std::cerr << __FILE__ << ":" << __LINE__ << ": o is NULL!\n";
    abort();
  }
}

答案 7 :(得分:0)

只是模糊地引用我的头脑:

#define assert(e)       ((e) ? (void)0 : printf("Assertion failed %s, %s : %s", #e, __FILE__, __LINE__))