C/C++ line number

C++CC PreprocessorLine NumbersDynamic Compilation

C++ Problem Overview


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)

C++ Solutions


Solution 1 - C++

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__);

Solution 2 - C++

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__);

Solution 3 - C++

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!

Solution 4 - C++

Use __LINE__ (that's double-underscore LINE double-underscore), the preprocessor will replace it with the line number on which it is encountered.

Solution 5 - C++

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>.

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:

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:

#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.

Solution 6 - C++

Checkout __FILE__ and __LINE__ macros

Solution 7 - C++

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.

Solution 8 - C++

For those who might need it, a "FILE_LINE" macro to easily print file and line:

#define STRINGIZING(x) #x
#define STR(x) STRINGIZING(x)
#define FILE_LINE __FILE__ ":" STR(__LINE__)

Solution 9 - C++

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.

Solution 10 - C++

Use __LINE__, but what is its type?

> LINE The presumed line number (within the current source file) of the current source line (an integer constant).

As an integer constant, code can often assume the value is __LINE__ <= INT_MAX and so the type is int.

To print in C, printf() needs the matching specifier: "%d". This is a far lesser concern in C++ with cout.

Pedantic concern: If the line number exceeds INT_MAX1 (somewhat conceivable with 16-bit int), hopefully the compiler will produce a warning. Example:

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()

To avoid all integer limitations: stringify. Code could directly print without a printf() call: a nice thing to avoid in error handling2 .

#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);

1 Certainly poor programming practice to have such a large file, yet perhaps machine generated code may go high.

2 In debugging, sometimes code simply is not working as hoped. Calling complex functions like *printf() can itself incur issues vs. a simple fputs().

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBetamooView Question on Stackoverflow
Solution 1 - C++Julien HoarauView Answer on Stackoverflow
Solution 2 - C++Brian R. BondyView Answer on Stackoverflow
Solution 3 - C++Some Java ProgrammerView Answer on Stackoverflow
Solution 4 - C++user229044View Answer on Stackoverflow
Solution 5 - C++sirainView Answer on Stackoverflow
Solution 6 - C++AntonView Answer on Stackoverflow
Solution 7 - C++Sanctus2099View Answer on Stackoverflow
Solution 8 - C++clarkttfuView Answer on Stackoverflow
Solution 9 - C++John DoeView Answer on Stackoverflow
Solution 10 - C++chux - Reinstate MonicaView Answer on Stackoverflow