__func__ 是标准c++11起最简单可靠的函数名获取方式,为隐式const char[]变量,值为当前函数未修饰名,零开销、跨平台,但不适用于宏或获取调用者函数名。

__func__ 是最简单可靠的方案
在标准 C++11 及以后,__func__ 是语言内置的隐式局部变量,类型为 const char[],值为当前函数名(不含命名空间或类作用域)。它不是宏,不依赖编译器扩展,可直接用,且开销几乎为零。
-
__func__在函数体内任意位置都有效,包括 lambda 内部(C++17 起) - 它返回的是未经修饰的函数名,比如
void foo::bar() {}中__func__值是"bar",不是"foo::bar" - 不能用于宏定义里取调用点函数名——那是
__FUNCTION__或__PRETTY_FUNCTION__的事,但它们非标准、行为不一
需要完整签名时用 __PRETTY_FUNCTION__(GCC/Clang)
如果调试或日志需要带参数类型、返回值、模板实例化信息的函数描述,__PRETTY_FUNCTION__ 更有用,但它不是标准 C++,仅 GCC 和 Clang 支持,MSVC 不识别。
- 在模板函数中,
__PRETTY_FUNCTION__会展开实际类型,例如template<typename t> void f(T) {}</typename>调用f(42)时输出类似"void f(int)" - MSVC 对应的是
__FUNCSIG__,内容格式不同,不可跨平台混用 - 注意:这些字符串在编译期生成,长度可能很大,避免频繁用于高频日志(尤其在嵌入式或性能敏感场景)
想获取调用者函数名?别依赖 __func__
__func__ 永远返回「当前函数」的名字,不是调用它的那个函数。如果想实现类似 Python 的 inspect.stack() 效果,C++ 没有标准方式,必须借助平台特定手段:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- GCC/Clang 可用
__builtin_return_address(0)+backtrace()+abi::__cxa_demangle()解析,但结果不稳定,且无法保证符号未被 strip - Windows 下可用
CaptureStackBackTrace()配合SymFromAddr(),需初始化 dbghelp.dll 且链接对应库 - 所有栈回溯方案都禁用优化(
-O0)、关闭内联(-fno-inline),否则帧信息丢失严重
宏封装要注意字符串生命周期
有人会写 #define LOG_FUNC() std::cout ,这没问题;但若试图保存指针,比如 <code>const char* name = __func__; 然后返回或存到全局,就危险了——__func__ 是函数作用域内的静态存储期数组,离开函数后指针悬空。
- 安全做法:当场使用,或用
std::string(__func__)复制一份 - 不要在 constexpr 上下文中用
__func__——它不是字面量,C++20 前无法用于编译期计算 - 如果函数名要参与编译期逻辑(如类型名拼接),只能靠宏(如
__FUNCTION__)+ 预处理器,但会失去类型安全和 IDE 支持
真正麻烦的从来不是“怎么拿到名字”,而是后续怎么用——传参、日志格式、是否跨线程、要不要 demangle、有没有符号表,每个环节都可能悄悄破坏预期。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










