Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a value of __LINE__ of another function (before calling that function)?

Tags:

c++

c

For the currently existing test framework I need to pass (during the first-most call) to the function a line number of a fragment inside of that function. Something like this:

#include <stdio.h>
void func(int line_num)
{
#define LINE_NUM  (__LINE__ + 1)
  if(line_num == __LINE__) // Check the passed arg against the current line.
    printf("OK");
  else
    printf("FAIL");
}

int main(void)
{
  func(LINE_NUM); // Pass to the func the line number inside of that func.
  return 0;
}

(this is a minimalistic version of a more complex functionality).

As is the sample code prints "FAIL".

If I pass an absolute value 5, e.g. func(5) then it prints "OK". I don't like the absolute value 5 because if I add one more line in front of the func definition then the absolute value will need a correction.

Instead of #define LINE_NUM (__LINE__ + 1) I also tried the following:

1.

#define VALUE_OF(x) x
#define LINE_NUM    (VALUE_OF(__LINE__) + 1)

2.

#define VAL(a,x)    a##x
#define LOG_LINE()    ( VAL( /*Nothing*/,__LINE__) + 1)

3.

#define VALUE_OF2(x) x
#define VALUE_OF(x)     VALUE_OF2(x)
#define LINE_NUM  (VALUE_OF(__LINE__) + 1)

I'm using:

gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

In my sample code the value that func() gets is 14 (the call site line number + 1).

like image 956
Robin Kuzmin Avatar asked Nov 16 '17 01:11

Robin Kuzmin


People also ask

What is __ LINE __ in C++?

__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

What does __ LINE __ return?

The __LINE__ is an inbuilt Macro in C programming language, it returns current line number of the code.

What is __ file __ in C?

__FILE__ This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ' #include ' or as the input file name argument. For example, "/usr/local/include/myheader.

How do I print line numbers in CPP?

The standard solution to find the current line number in C++ is using the predefined macro __LINE__ . It returns the integer value representing the current line in the source code file being compiled. The preprocessor will simply replace the __LINE__ macro with the current line number.


1 Answers

You cannot get the preprocessor to expand __LINE__ in a macro definition. That's not the way the preprocessor works.

But you can create global constants.

#include <stdio.h>

static const int func_line_num = __LINE__ + 3;
void func(int line_num)
{
  if(line_num == __LINE__) // Check the passed arg against the current line.
    printf("OK");
  else
    printf("FAIL");
}

int main(void)
{
  func(func_line_num); // Pass to the func the line number inside of that func.
  return 0;
}

If you don't like static const int, for whatever reason, you could use an enum:

enum { FUNC_LINE_NUM = __LINE__ + 3 };

Unfortunately, whether you use a global constant or an enum, you have to put the definition at file scope, which might make it somewhat distant from the use point. However, it is not immediately apparent why the precise line number of the test needs to be used, rather than (for example) the first line of the function or even any integer guaranteed to be unique:

#include <stdio.h>

// As long as all uses of __LINE__ are on different lines, the
// resulting values will be different, at least within this file.
enum { FUNC_LINE_NUM = __LINE__ };

void func(int line_num)
{
  if(line_num == FILE_LINE_NUM) // Check the passed arg against the appropriate constant.
    printf("OK");
  else
    printf("FAIL");
}

int main(void)
{
  func(func_line_num); // Pass to the func the line number inside of that func.
  return 0;
}
like image 118
rici Avatar answered Oct 14 '22 22:10

rici