繁体   English   中英

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

[英]Why would you use the __LINE__ macro in C++

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

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

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

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

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

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

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

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

我为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__ ,就像使用方便一样。

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

像这样:

$ 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
$
if (something truly impossible has happened) {
   fprintf(stderr, "Value of PI less than 3 detected at %s line %d\n", __FILE__, __LINE__);
}

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM