c++cgccc-preprocessor

How to concat __func__ and __LINE__ in a macro definition


I would like to define a macro to concat __func__ (or __FUNCTION__) with __LINE__:

The following works fine:

// macro_test.cc
#include <iostream>

#define STR2(X) #X
#define STR(X) STR2(X)
#define FILE_LOCATION __FILE__ ":" STR(__LINE__) " "

int main() {
  std::cout << FILE_LOCATION << "is <file_name>:<line_number>" << std::endl;
  return 0;
}

And here is the output

$ ./a.out 
macro_test.cc:8 is <file_name>:<line_number>

However the following gives a compilation error (I just replaced __FILE__ with __func__):

// macro_test.cc
#include <iostream>

#define STR2(X) #X
#define STR(X) STR2(X)
#define FUNC_LOCATION __func__ ":" STR(__LINE__) " "

int main() {
  std::cout << FUNC_LOCATION << "is <function_name>:<line_number>" << std::endl;
  return 0;
}

~$ gcc macro_test.cc 
macro_test.cc: In function ‘int main()’:
macro_test.cc:5:32: error: expected ‘;’ before string constant
 #define FUNC_LOCATION __func__ ":" STR(__LINE__) " "
                                ^
macro_test.cc:8:16: note: in expansion of macro ‘FUNC_LOCATION’
   std::cout << FUNC_LOCATION << "is <function_name>:<line_number>" << std::endl;

Does anyone know the reason for this and how can I achieve this?

I am using gcc 5.4.0 on Linux (Ubuntu 18.04).


Solution

  • gives a compilation error [...] anyone know the reason for this

    __func__ is a variable:

    static const char __func__[] = "function-name";
    

    It is not to a (string) literal (to which for example __FILE__ "expands".)

    (docs are here: https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html)