如何在宏定义中连接 __func__ 和 __LINE__
How to concat __func__ and __LINE__ in a macro definition
我想定义一个宏来连接 __func__
(或 __FUNCTION__
)与 __LINE__
:
以下工作正常:
// 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;
}
这是输出
$ ./a.out
macro_test.cc:8 is <file_name>:<line_number>
但是下面给出了一个编译错误(我只是用__func__
替换了__FILE__
:
// 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;
有人知道这是什么原因吗?我该如何实现?
我在 Linux (Ubuntu 18.04) 上使用 gcc 5.4.0。
gives a compilation error [...] anyone know the reason for this
__func__
是一个变量:
static const char __func__[] = "function-name";
不是一个(字符串)文字(例如__FILE__
"expands"。)
(文档在这里:https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html)
与其尝试将不兼容的类型拼接成单个字符串,不如使用 立即调用的函数表达式(借用 JavaScript 术语)作为宏实现.
因为是立即执行,所以我传入两个预处理器标识符作为参数。
不应将它们烘焙到 lambda 的主体中,因为这样 __func__
将反映 lambda 而不是调用 lambda 的例程。
#include <sstream>
#define FUNC_LOCATION \
[](auto fn, auto ln) { \
std::stringstream ss;
ss << fn << ":" << ln << " "; \
return ss.str(); \
}(__func__, __LINE__)
int main() {
std::cout << FILE_LOCATION << "is <file_name>:<line_number>" << std::endl;
return 0;
}
我想定义一个宏来连接 __func__
(或 __FUNCTION__
)与 __LINE__
:
以下工作正常:
// 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;
}
这是输出
$ ./a.out
macro_test.cc:8 is <file_name>:<line_number>
但是下面给出了一个编译错误(我只是用__func__
替换了__FILE__
:
// 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;
有人知道这是什么原因吗?我该如何实现?
我在 Linux (Ubuntu 18.04) 上使用 gcc 5.4.0。
gives a compilation error [...] anyone know the reason for this
__func__
是一个变量:
static const char __func__[] = "function-name";
不是一个(字符串)文字(例如__FILE__
"expands"。)
(文档在这里:https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html)
与其尝试将不兼容的类型拼接成单个字符串,不如使用 立即调用的函数表达式(借用 JavaScript 术语)作为宏实现.
因为是立即执行,所以我传入两个预处理器标识符作为参数。
不应将它们烘焙到 lambda 的主体中,因为这样 __func__
将反映 lambda 而不是调用 lambda 的例程。
#include <sstream>
#define FUNC_LOCATION \
[](auto fn, auto ln) { \
std::stringstream ss;
ss << fn << ":" << ln << " "; \
return ss.str(); \
}(__func__, __LINE__)
int main() {
std::cout << FILE_LOCATION << "is <file_name>:<line_number>" << std::endl;
return 0;
}