std::source_location::function_name()仅返回编译器生成的原始符号名,不可读且不可移植;完整可读签名需依赖__pretty_function__(gcc/clang)或__funcsig__(msvc)宏,二者非标准但稳定可用,与std::source_location互补。

std::source_location 本身不提供函数签名
直接用 std::source_location::function_name() 只会返回编译器生成的原始符号名(如 "foo" 或 "N5mylib3BarE3bazEv"),不是可读的完整签名,也不带命名空间。它本质上是编译器内建字符串字面量,内容取决于 ABI 和编译选项,不可靠也不可移植。
需要配合 __PRETTY_FUNCTION__ 或 __FUNCSIG__ 宏
真正能拿到带命名空间、参数、返回类型的完整签名的,是编译器扩展宏:__PRETTY_FUNCTION__(GCC/Clang)或 __FUNCSIG__(MSVC)。std::source_location 只负责定位(文件/行/列),签名得另找来源。
-
__PRETTY_FUNCTION__在 GCC/Clang 下输出类似"void mylib::Bar::baz() const"的可读字符串 -
__FUNCSIG__在 MSVC 下输出类似"void mylib::Bar::baz(void) const" - 两者都不是标准 C++,但稳定可用;
std::source_location是 C++20 标准,二者互补而非替代
安全封装:运行时 demangle + 编译器宏 fallback
如果想统一接口并尽量可读,可以这样写:
#include <source_location>
#include <string>
#include <typeinfo>
#include <memory>
#ifdef __GNUC__
# include <cxxabi.h>
#endif
<p>std::string full_signature(
const std::source_location& loc = std::source_location::current()) {</p>
<h1>if defined(<strong>GNUC</strong>) || defined(<strong>clang</strong>)</h1>
<p>int status;
std::unique_ptr<char void>)(void)> demangled(
abi::__cxa_demangle(loc.function_name(), nullptr, nullptr, &status),
[](void* p) { std::free(p); });
return status == 0 ? demangled.get() : loc.function_name();</char></p>
<h1>elif defined(_MSC_VER)</h1>
<p>return <strong>FUNCSIG</strong>;</p>
<h1>else</h1>
<p>return loc.function_name(); // fallback</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<h1>endif</h1>
<p>}
</p></cxxabi.h></memory></typeinfo></string></source_location>
注意:__cxa_demangle 只对 mangled 名有效;而 __PRETTY_FUNCTION__ 已经是 demangled 的,直接用更稳妥 —— 所以上面例子其实更适合用 __PRETTY_FUNCTION__ 替代 loc.function_name(),避免误 demangle 已解码字符串。
实际打印时别只依赖 source_location::function_name()
常见错误是这么写:
auto loc = std::source_location::current(); std::cout <p>正确做法是显式组合:</p>
- 调试输出优先用
__PRETTY_FUNCTION__(GCC/Clang)或__FUNCSIG__(MSVC) - 需要文件/行号时再叠加
std::source_location的file_name()和line() - 不要试图从
function_name()解析命名空间 —— 它在不同编译器下格式不一致,且可能为空或为简名
最简可靠方案就是放弃 function_name() 做签名,老实用宏。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










