我正在开发一个嵌入式系统,在使用 nm 分析二进制文件时,我发现了许多来自标准库函数的符号,例如:
00001524 std::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_via_format(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, tm*, char const*) const [clone .localalias]
Run Code Online (Sandbox Code Playgroud)
这意味着有一个std::time_get函数被链接进来,该函数大小为 1524 字节。我想找出是什么调用链导致了调用,std::time_get因为我实际上并没有在代码的任何部分中引用它。
尝试使用链接器标志--cref并查看映射文件,我可以找到该符号,但找不到调用它的内容。它只告诉我libstdc++_nano.a(locale-inst.o)引用它:
.text._ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc
0x00000000080a07bc 0x5fc /opt/st/stm32cubeide_1.10.1/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.linux64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+dp/hard/libstdc++_nano.a(locale-inst.o)
0x00000000080a07bc std::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_via_format(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, tm*, char const*) const
Run Code Online (Sandbox Code Playgroud)
我怎样才能从那里找到呼叫者?
给定一个 constexpr 函数,是否有办法在编译时调用该函数时创建编译时错误,并在运行时调用该函数时返回哨兵值?
不幸的是,我无法使用异常,因为它们在构建中被禁用。
这主要用于与枚举之间的转换以及与字符串之间的转换。如果开发人员输入了不正确的值,最好让构建失败,而不是希望他们在运行时看到错误,但由于我们可以从未知来源获取值,因此该值有可能无效,我们不这样做不想在运行时崩溃。
演示用例:
#include <fmt/core.h>
#include <iostream>
// from: https://stackoverflow.com/a/63529662/4461980
// if C++20, we will need a <type_traits> include for std::is_constant_evaluated
#if __cplusplus >= 202002L
#include <type_traits>
#endif
constexpr bool is_constant_evaluated() {
#if __cplusplus >= 202002L
return std::is_constant_evaluated();
#elif defined(__GNUC__) // defined for both GCC and clang
return __builtin_is_constant_evaluated();
#else
// If the builtin is not available, return a pessimistic result.
// This way callers will implement everything in a constexpr way.
return true;
#endif
}
enum …Run Code Online (Sandbox Code Playgroud)