__function__ 是 c++ 标准支持的预定义标识符,能安全获取当前函数名字符串字面量;它在 msvc vs2015+ 与 __func__ 等价,编译期替换为 const char*,零运行开销,常用于跨平台日志宏。

直接说结论:__FUNCTION__ 是 C++ 标准支持的预定义标识符,能安全获取当前函数名字符串字面量,无需额外头文件或编译器扩展。
为什么 __FUNCTION__ 比 __func__ 更常用?
__func__ 是 C99 和 C++11 起引入的正规标准宏(严格来说是隐式声明的静态 const char 数组),而 __FUNCTION__ 是 GCC/Clang/MSVC 都支持的扩展——实际使用中三者行为一致,但 __FUNCTION__ 在旧代码、跨平台日志宏里更常见。
-
__FUNCTION__在 MSVC 中从 VS2015 起完全等价于__func__;VS2013 及更早需启用/Zc:__FUNCTION__ - 它不是函数调用,不产生运行时开销,编译期就替换成字符串字面量
- 返回的是
const char*,不是std::string,避免隐式构造和内存分配
在日志宏中怎么安全拼接文件名、行号和函数名?
典型错误是直接用 std::cout 拼接,结果因类型推导失败或临时对象生命周期问题导致乱码。正确做法是统一用字符串字面量 + 宏展开:
#define LOG(fmt, ...) \
fprintf(stderr, "[%s:%d %s] " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
- 必须用
fprintf或printf系列——__FUNCTION__是字面量,可直接参与字符串字面量拼接(C++11 起支持) - 避免写成
std::string(__FUNCTION__) + " msg":每次触发堆分配,且无法在 constexpr 上下文中使用 - 如果要用
std::format(C++20),需显式转为std::string_view:std::format("in {}", std::string_view{__FUNCTION__})
__FUNCTION__ 在模板函数里返回什么?
它返回实例化后的函数签名全名,不是模板定义处的泛型名。例如:
立即学习“C++免费学习笔记(深入)”;
template<typename T> void foo(T) { printf("%s\n", __FUNCTION__); }
foo(42); // 输出类似 "foo<int>"
foo(3.14); // 输出类似 "foo<double>"
- MSVC 输出带
class/struct关键字(如foo<class std::string></class>) - GCC/Clang 默认输出精简版,加
-fverbose-asm不影响此行为,但调试信息会更全 - 若只需函数名不含模板参数,得手动截断——
__FUNCTION__本身不提供解析能力
真正容易被忽略的是:它在内联函数、lambda 表达式、以及 constexpr 函数中依然有效,但 lambda 的 __FUNCTION__ 值由编译器生成(如 operator() 或匿名名称),不可移植依赖。需要稳定标识时,应显式命名 lambda 或改用普通函数。











