问题
In the sake of debugging purposes, can I get the line number in C/C++ compilers? (standard way or specific ways for certain compilers)
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)
回答1:
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.
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"
Your code will be :
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
回答2:
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.
__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
So your code would be:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
回答3:
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:
#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:
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!
回答4:
Use __LINE__
(that's double-underscore LINE double-underscore), the preprocessor will replace it with the line number on which it is encountered.
回答5:
Checkout __FILE__
and __LINE__
macros
回答6:
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.
回答7:
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.
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.
#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
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.
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.
回答8:
C++20 offers a new way to achieve this by using std::source_location. This is currently accessible in as std::experimental::source_location
.
The problem with macros like __LINE__
is that if you want to create a, 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:
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.
On the other hand, with std::source_location
you can write something like this:
void log(const std::string msg,
const std::source_location loc = std::experimental::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.
来源:https://stackoverflow.com/questions/2849832/c-c-line-number