C/C++ 行号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2849832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C/C++ line number
提问by Betamoo
In the sake of debugging purposes, can I get the line number in C/C++ compilers? (standard way or specific ways for certain compilers)
出于调试目的,我可以在C/C++ 编译器中获取行号吗?(某些编译器的标准方式或特定方式)
e.g
例如
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
回答by Julien Hoarau
You should use the preprocessor macro __LINE__
and __FILE__
. They are predefined macros and part of the C/C++ standard. During preprocessing, they are replaced respectively by a constant string holding an integer representing the current line number and by the current file name.
您应该使用预处理器宏__LINE__
和__FILE__
. 它们是预定义的宏,是 C/C++ 标准的一部分。在预处理过程中,它们分别被一个包含代表当前行号的整数的常量字符串和当前文件名替换。
Others preprocessor variables :
其他预处理器变量:
__func__
: function name (this is part of C99, not all C++ compilers support it)__DATE__
: a string of form "Mmm dd yyyy"__TIME__
: a string of form "hh:mm:ss"
__func__
: 函数名(这是C99 的一部分,并非所有 C++ 编译器都支持它)__DATE__
: 形式为“Mmm dd yyyy”的字符串__TIME__
: 形式为 "hh:mm:ss" 的字符串
Your code will be :
您的代码将是:
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
回答by Brian R. Bondy
As part of the C++ standard there exists some pre-defined macros that you can use. Section 16.8 of the C++ standard defines amongst other things, the __LINE__
macro.
作为 C++ 标准的一部分,存在一些您可以使用的预定义宏。C++ 标准的第 16.8 节定义了__LINE__
宏。
__LINE__
:The line number of the current source line (a decimal constant).__FILE__
:The presumed name of the source file (a character string literal).__DATE__
:The date of translation of the source file (a character string literal...)__TIME__
:The time of translation of the source file (a character string literal...)__STDC__
:Whether__STDC__
is predefined__cplusplus
:The name__cplusplus
is defined to the value 199711L when compiling a C ++ translation unit
__LINE__
:当前源行的行号(十进制常量)。__FILE__
:源文件的假定名称(字符串文字)。__DATE__
:源文件的翻译日期(字符串字面量...)__TIME__
:源文件的翻译时间(字符串字面量...)__STDC__
:是否__STDC__
预定义__cplusplus
:名称__cplusplus
定义为值 199711L 时编译一个 C++ 翻译单元
So your code would be:
所以你的代码是:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
回答by Some Java Programmer
You could use a macro with the same behavior as printf(), except that it also includes debug information such as function name, class, and line number:
您可以使用与printf()具有相同行为的宏,但它还包括调试信息,例如函数名称、类和行号:
#include <cstdio> //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a, __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)
These macros should behave identically to printf(), while including java stacktrace-like information. Here's an example main:
这些宏的行为应该与printf()相同,同时包含类似 java 堆栈跟踪的信息。这是一个主要的例子:
void exampleMethod() {
println("printf() syntax: string = %s, int = %d", "foobar", 42);
}
int main(int argc, char** argv) {
print("Before exampleMethod()...\n");
exampleMethod();
println("Success!");
}
Which results in the following output:
这导致以下输出:
main(main.cpp:11) Before exampleMethod()...
exampleMethod(main.cpp:7) printf() syntax: string = foobar, int = 42
main(main.cpp:13) Success!
main(main.cpp:11) 在exampleMethod()之前...
exampleMethod(main.cpp:7) printf() 语法:string = foobar, int = 42
main(main.cpp:13) 成功!
回答by meagar
Use __LINE__
(that's double-underscore LINE double-underscore), the preprocessor will replace it with the line number on which it is encountered.
使用__LINE__
(即双下划线 LINE 双下划线),预处理器将用遇到它的行号替换它。
回答by Anton
Checkout __FILE__
and __LINE__
macros
结帐__FILE__
和__LINE__
宏
回答by Sanctus2099
Try __FILE__
and __LINE__
.
You might also find __DATE__
and __TIME__
useful.
Though unless you have to debug a program on the clientside and thus need to log these informations you should use normal debugging.
尝试__FILE__
和__LINE__
。
您可能还会发现__DATE__
并__TIME__
有用。
但是除非您必须在客户端调试程序并因此需要记录这些信息,否则您应该使用正常调试。
回答by sirain
C++20 offers a new way to achieve this by using std::source_location. This is currently accessible in gcc an clang as std::experimental::source_location
with #include <experimental/source_location>
.
C++20 通过使用std::source_location提供了一种新方法来实现这一点。这是目前在海湾合作委员会的铛可访问std::experimental::source_location
与#include <experimental/source_location>
。
The problem with macros like __LINE__
is that if you want to create for example a logging function that outputs the current line number along with a message, you always have to pass __LINE__
as a function argument, because it is expanded at the call site.
Something like this:
宏的问题__LINE__
是,如果你想创建例如一个输出当前行号和消息的日志函数,你总是必须__LINE__
作为函数参数传递,因为它在调用站点被扩展。像这样的东西:
void log(const std::string msg) {
std::cout << __LINE__ << " " << msg << std::endl;
}
Will always output the line of the function declaration and not the line where log
was actually called from.
On the other hand, with std::source_location
you can write something like this:
将始终输出函数声明的行而不是log
实际调用的行。另一方面,std::source_location
你可以这样写:
#include <experimental/source_location>
using std::experimental::source_location;
void log(const std::string msg, const source_location loc = source_location::current())
{
std::cout << loc.line() << " " << msg << std::endl;
}
Here, loc
is initialized with the line number pointing to the location where log
was called.
You can try it online here.
在这里,loc
用指向log
调用位置的行号初始化。
您可以在此处在线试用。
回答by chux - Reinstate Monica
Use __LINE__
, but what is its type?
使用__LINE__
,但它的类型是什么?
LINEThe presumed line number (within the current source file) of the current source line (an integer constant).
LINE当前源行的假定行号(在当前源文件中)(整数常量)。
As an integer constant, code can often assume the value is __LINE__ <= INT_MAX
and so the type is int
.
作为整数常量,代码通常可以假定值是__LINE__ <= INT_MAX
,因此类型是 int
。
To print in C, printf()
needs the matching specifier: "%d"
. This is a far lesser concern in C++ with cout
.
要在 C 中打印,printf()
需要匹配的说明符:"%d"
。在使用cout
.
Pedantic concern:If the line number exceeds INT_MAX
1(somewhat conceivable with 16-bit int
), hopefully the compiler will produce a warning. Example:
迂腐的问题:如果行号超过INT_MAX
1(对于 16-bit 有点可以想象int
),希望编译器会产生警告。例子:
format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
Alternatively, code could force wider types to forestall such warnings.
或者,代码可以强制使用更广泛的类型来阻止此类警告。
printf("Not logical value at line number %ld\n", (long) __LINE__);
//or
#include <stdint.h>
printf("Not logical value at line number %jd\n", INTMAX_C(__LINE__));
Avoid printf()
避免 printf()
To avoid all integer limitations: stringify. Code could directly print without a printf()
call: a nice thing to avoid in error handling2.
为避免所有整数限制:stringify。代码无需printf()
调用即可直接打印:在错误处理中避免的一件好事2。
#define xstr(a) str(a)
#define str(a) #a
fprintf(stderr, "Not logical value at line number %s\n", xstr(__LINE__));
fputs("Not logical value at line number " xstr(__LINE__) "\n", stderr);
1Certainly poor programming practice to have such a large file, yet perhaps machine generated code may go high.
1拥有如此大的文件肯定是糟糕的编程实践,但也许机器生成的代码可能会很高。
2In debugging, sometimes code simply is not working as hoped. Calling complex functions like *printf()
can itself incur issues vs. a simple fputs()
.
2在调试中,有时代码根本无法按预期工作。像调用复杂功能*printf()
本身可以招致问题与简单fputs()
。
回答by John Doe
Since i'm also facing this problem now and i cannot add an answer to a different but also valid question asked here, i'll provide an example solution for the problem of: getting only the line number of where the function has been called in C++ using templates.
由于我现在也面临这个问题,我无法为这里提出的不同但也是有效的问题添加答案,我将为以下问题提供一个示例解决方案:仅获取调用函数的行号C++ 使用模板。
Background: in C++ one can use non-type integer values as a template argument. This is different than the typical usage of data types as template arguments. So the idea is to use such integer values for a function call.
背景:在 C++ 中,可以使用非类型整数值作为模板参数。这与数据类型作为模板参数的典型用法不同。所以我们的想法是在函数调用中使用这样的整数值。
#include <iostream>
class Test{
public:
template<unsigned int L>
int test(){
std::cout << "the function has been called at line number: " << L << std::endl;
return 0;
}
int test(){ return this->test<0>(); }
};
int main(int argc, char **argv){
Test t;
t.test();
t.test<__LINE__>();
return 0;
}
Output:
输出:
the function has been called at line number: 0
the function has been called at line number: 16
该函数已在行号处调用:0
该函数已在第 16 行调用
One thing to mention here is that in C++11 Standard it's possible to give default template values for functions using template. In pre C++11 default values for non-type arguments seem to only work for class template arguments. Thus, in C++11, there would be no need to have duplicate function definitions as above. In C++11 its also valid to have const char* template arguments but its not possible to use them with literals like __FILE__
or __func__
as mentioned here.
这里要提到的一件事是,在 C++11 标准中,可以使用模板为函数提供默认模板值。在 C++11 之前,非类型参数的默认值似乎只适用于类模板参数。因此,在 C++11 中,不需要像上面那样有重复的函数定义。在C ++ 11的也是有效的具有为const char *模板参数,但它不可能与像文字使用它们__FILE__
或__func__
如提到这里。
So in the end if you're using C++ or C++11 this might be a very interesting alternative than using macro's to get the calling line.
所以最后,如果你使用 C++ 或 C++11,这可能是一个非常有趣的替代方案,而不是使用宏来获取调用行。
回答by clarkttfu
For those who might need it, a "FILE_LINE" macro to easily print file and line:
对于那些可能需要它的人,一个“FILE_LINE”宏可以轻松打印文件和行:
#define STRINGIZING(x) #x
#define STR(x) STRINGIZING(x)
#define FILE_LINE __FILE__ ":" STR(__LINE__)