Test version : 10.2.1
Test code snippet:
std::locale::global(loc); auto sat = fmt::weekday(6); fmt::format(loc, "{:L}", sat);
The code above will throw std::bad_cast
when using specifed compiler and OS.
Compiler: g++ (GCC) 12.2.1 20221121 (Red Hat 12.2.1-4)
OS: CentOS 7.6
This gcc is from RHEL Dev tool set 12: https://access.redhat.com/documentation/en-us/red_hat_developer_toolset/12
Root cause: This compile has predefined #define _GLIBCXX_USE_DUAL_ABI 0
, the old CentOS 7.6 do not support dual ABI, but the _GLIBCXX_USE_DUAL_ABI
IS defined to 0, not undefined.
And related code in include/fmt/chrono.h
:
template <typename OutputIt> auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) -> OutputIt { if (detail::is_utf8() && loc != get_classic_locale()) { // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and // gcc-4. #if FMT_MSC_VERSION != 0 || \ (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)) // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5 // and newer. using code_unit = wchar_t; #else using code_unit = char32_t; #endif using unit_t = codecvt_result<code_unit>; unit_t unit; write_codecvt(unit, in, loc); // ...... }
If _GLIBCXX_USE_DUAL_ABI
IS defined, std::use_facet<std::codecvt<char32_t, char, std::mbstate_t>>(loc)
will be called in write_codecvt()
, which throw std::bad_cast
. If I only keep using code_unit = wchar_t;
here, the code above can work well.
I think we should not only check whether _GLIBCXX_USE_DUAL_ABI
is defined, but also check it's value here:
#if FMT_MSC_VERSION != 0 || \ (defined(__GLIBCXX__) && (!defined(_GLIBCXX_USE_DUAL_ABI) || _GLIBCXX_USE_DUAL_ABI == 0 ))
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4