我想弄清楚人们如何在工作中使用__LINE__
宏。你们是如何使用它的?
答案 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__))