> On 29 Dec 2024, at 15:16, Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > > On Sun, 29 Dec 2024 at 10:01, Hans Åberg via Gcc-help > <gcc-help@xxxxxxxxxxx> wrote: >> >> When checking the GCC 14.2 implementation of C++23 fixed width floating-point types in the header <stdfloat> [1]: >> >> The page [2] says that one should be able to write std::float128_t using std::formatter as it is using std::to_chars which is required to support all arithmetic type, but it does not work with GCC. > > It works fine for me. > >> But the wording suggests it has been working with GCC. > > And still is working. > > If it's not working for you, it must be a limitation of your OS, which > you haven't told us. It is MacOS 15.2, Silicon, but I think the error is the same on Intel, with % g++ --version g++ (MacPorts gcc14 14.2.0_3+stdlib_flag) 14.2.0 Using g++ -std=c++23 for: #include <iostream> #include <stdfloat> #include <format> int main() { std::cout << std::format("{}", std::float128_t{1.0}) << '\n'; return 0; } I get the error: % g++ -std=c++23 float128.cc -o float128 In file included from /opt/local/include/gcc14/c++/ostream:43, from /opt/local/include/gcc14/c++/iostream:41, from float128.cc:2: /opt/local/include/gcc14/c++/format: In instantiation of 'class std::__format::_Checking_scanner<char, _Float128>': /opt/local/include/gcc14/c++/format:4207:4: required from 'consteval std::basic_format_string<_CharT, _Args>::basic_format_string(const _Tp&) [with _Tp = char [3]; _CharT = char; _Args = {_Float128}]' 4207 | __scanner(_M_str); | ^~~~~~~~~ float128.cc:7:27: required from here 7 | std::cout << std::format("{}", std::float128_t{1.0}) << '\n'; | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:4062:10: error: static assertion failed: std::formatter must be specialized for each type being formatted 4062 | (is_default_constructible_v<formatter<_Args, _CharT>> && ...), | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:4062:10: note: 'std::is_default_constructible_v<std::formatter<_Float128, char> >' evaluates to false /opt/local/include/gcc14/c++/format: In instantiation of 'constexpr void std::__format::_Checking_scanner<_CharT, _Args>::_M_parse_format_spec(std::size_t) [with _Tp = _Float128; _OtherArgs = {}; _CharT = char; _Args = {_Float128}; std::size_t = long unsigned int]': /opt/local/include/gcc14/c++/format:4079:33: required from here 4079 | _M_parse_format_spec<_Args...>(__id); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~ float128.cc:7:27: in 'constexpr' expansion of 'std::basic_format_string<char, _Float128>("{}")' /opt/local/include/gcc14/c++/format:4208:19: in 'constexpr' expansion of '__scanner.std::__format::_Checking_scanner<char, _Float128>::std::__format::_Scanner<char>.std::__format::_Scanner<char>::_M_scan()' /opt/local/include/gcc14/c++/format:3915:19: in 'constexpr' expansion of '((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_format_arg(((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_pc.std::basic_format_parse_context<char>::next_arg_id())' /opt/local/include/gcc14/c++/format:4092:38: error: use of deleted function 'std::formatter<_Tp, _CharT>::formatter() [with _Tp = _Float128; _CharT = char]' 4092 | formatter<_Tp, _CharT> __f; | ^~~ /opt/local/include/gcc14/c++/format:178:7: note: declared here 178 | formatter() = delete; // No std::formatter specialization for this type. | ^~~~~~~~~ /opt/local/include/gcc14/c++/format:4092:38: note: use '-fdiagnostics-all-candidates' to display considered candidates 4092 | formatter<_Tp, _CharT> __f; | ^~~ /opt/local/include/gcc14/c++/format:4093:42: error: 'struct std::formatter<_Float128, char>' has no member named 'parse' 4093 | this->_M_pc.advance_to(__f.parse(this->_M_pc)); | ~~~~^~~~~ float128.cc: In function 'int main()': float128.cc:7:27: error: call to consteval function 'std::basic_format_string<char, _Float128>("{}")' is not a constant expression 7 | std::cout << std::format("{}", std::float128_t{1.0}) << '\n'; | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format: In instantiation of 'static std::__format::_Arg_store<_Context, _Args>::_Element_t std::__format::_Arg_store<_Context, _Args>::_S_make_elt(_Tp&) [with _Tp = _Float128; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _Args = {std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle}; _Element_t = std::__format::_Arg_store<std::basic_format_context<std::__format::_Sink_iter<char>, char>, std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle>::_Element_t]': /opt/local/include/gcc14/c++/format:3754:23: required from 'std::__format::_Arg_store<_Context, _Args>::_Arg_store(_Tp& ...) [with _Tp = {_Float128}; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _Args = {std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle}]' 3754 | : _M_args{_S_make_elt(__a)...} | ~~~~~~~~~~~^~~~~ /opt/local/include/gcc14/c++/format:3804:14: required from 'auto std::make_format_args(_Args& ...) [with _Context = basic_format_context<__format::_Sink_iter<char>, char>; _Args = {_Float128}]' 3804 | return _Store(__fmt_args...); | ^~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:4291:61: required from 'std::string std::format(format_string<_Args ...>, _Args&& ...) [with _Args = {_Float128}; string = __cxx11::basic_string<char>; format_string<_Args ...> = basic_format_string<char, _Float128>]' 4291 | { return std::vformat(__fmt.get(), std::make_format_args(__args...)); } | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ float128.cc:7:27: required from here 7 | std::cout << std::format("{}", std::float128_t{1.0}) << '\n'; | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:3732:25: error: static assertion failed: std::formatter must be specialized for the type of each format arg 3732 | static_assert(is_default_constructible_v<formatter<_Tq, _CharT>>, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:3732:25: note: 'std::is_default_constructible_v<std::formatter<_Float128, char> >' evaluates to false /opt/local/include/gcc14/c++/format:3743:38: error: no matching function for call to 'std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::basic_format_arg(_Float128&)' 3743 | basic_format_arg<_Context> __arg(__v); | ^~~~~ /opt/local/include/gcc14/c++/format:3477:9: note: candidate: 'template<class _Tp> requires __formattable_with<_Tp, _Context, typename _Context::formatter_type<typename std::remove_const<_Tp>::type>, std::basic_format_parse_context<typename _Context::char_type> > std::basic_format_arg<_Context>::basic_format_arg(_Tp&) [with _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>]' 3477 | basic_format_arg(_Tp& __v) noexcept | ^~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:3477:9: note: template argument deduction/substitution failed: /opt/local/include/gcc14/c++/format:3477:9: note: constraints not satisfied In file included from /opt/local/include/gcc14/c++/compare:40, from /opt/local/include/gcc14/c++/bits/char_traits.h:56, from /opt/local/include/gcc14/c++/ios:42, from /opt/local/include/gcc14/c++/ostream:40: /opt/local/include/gcc14/c++/concepts: In substitution of 'template<class _Tp> requires __formattable_with<_Tp, _Context, typename _Context::formatter_type<typename std::remove_const<_Tp>::type>, std::basic_format_parse_context<typename _Context::char_type> > std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::basic_format_arg(_Tp&) [with _Tp = std::basic_format_context<std::__format::_Sink_iter<char>, char>]': /opt/local/include/gcc14/c++/format:3743:31: required from 'static std::__format::_Arg_store<_Context, _Args>::_Element_t std::__format::_Arg_store<_Context, _Args>::_S_make_elt(_Tp&) [with _Tp = _Float128; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _Args = {std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle}; _Element_t = std::__format::_Arg_store<std::basic_format_context<std::__format::_Sink_iter<char>, char>, std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle>::_Element_t]' 3743 | basic_format_arg<_Context> __arg(__v); | ^~~~~ /opt/local/include/gcc14/c++/format:3754:23: required from 'std::__format::_Arg_store<_Context, _Args>::_Arg_store(_Tp& ...) [with _Tp = {_Float128}; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _Args = {std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle}]' 3754 | : _M_args{_S_make_elt(__a)...} | ~~~~~~~~~~~^~~~~ /opt/local/include/gcc14/c++/format:3804:14: required from 'auto std::make_format_args(_Args& ...) [with _Context = basic_format_context<__format::_Sink_iter<char>, char>; _Args = {_Float128}]' 3804 | return _Store(__fmt_args...); | ^~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:4291:61: required from 'std::string std::format(format_string<_Args ...>, _Args&& ...) [with _Args = {_Float128}; string = __cxx11::basic_string<char>; format_string<_Args ...> = basic_format_string<char, _Float128>]' 4291 | { return std::vformat(__fmt.get(), std::make_format_args(__args...)); } | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ float128.cc:7:27: required from here 7 | std::cout << std::format("{}", std::float128_t{1.0}) << '\n'; | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/concepts:159:13: required for the satisfaction of 'constructible_from<_Tp, _Tp>' [with _Tp = std::formatter<_Float128, char>] /opt/local/include/gcc14/c++/concepts:173:13: required for the satisfaction of 'move_constructible<_Tp>' [with _Tp = std::formatter<_Float128, char>] /opt/local/include/gcc14/c++/concepts:178:13: required for the satisfaction of 'copy_constructible<_Tp>' [with _Tp = std::formatter<_Float128, char>] /opt/local/include/gcc14/c++/concepts:275:13: required for the satisfaction of 'copyable<_Tp>' [with _Tp = std::formatter<_Float128, char>] /opt/local/include/gcc14/c++/concepts:280:13: required for the satisfaction of 'semiregular<_Formatter>' [with _Formatter = std::formatter<_Float128, char>] /opt/local/include/gcc14/c++/format:2525:13: required for the satisfaction of '__formattable_with<_Tp, _Context, typename _Context::formatter_type<typename std::remove_const<_Tp>::type>, std::basic_format_parse_context<typename _Context::char_type> >' [with _Tp = _Float128; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>] /opt/local/include/gcc14/c++/concepts:160:30: note: the expression 'is_constructible_v<_Tp, _Args ...> [with _Tp = std::formatter<_Float128, char>; _Args = {std::formatter<_Float128, char>}]' evaluated to 'false' 160 | = destructible<_Tp> && is_constructible_v<_Tp, _Args...>; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format: In instantiation of 'static std::__format::_Arg_store<_Context, _Args>::_Element_t std::__format::_Arg_store<_Context, _Args>::_S_make_elt(_Tp&) [with _Tp = _Float128; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _Args = {std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle}; _Element_t = std::__format::_Arg_store<std::basic_format_context<std::__format::_Sink_iter<char>, char>, std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle>::_Element_t]': /opt/local/include/gcc14/c++/format:3754:23: required from 'std::__format::_Arg_store<_Context, _Args>::_Arg_store(_Tp& ...) [with _Tp = {_Float128}; _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _Args = {std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::handle}]' 3754 | : _M_args{_S_make_elt(__a)...} | ~~~~~~~~~~~^~~~~ /opt/local/include/gcc14/c++/format:3804:14: required from 'auto std::make_format_args(_Args& ...) [with _Context = basic_format_context<__format::_Sink_iter<char>, char>; _Args = {_Float128}]' 3804 | return _Store(__fmt_args...); | ^~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:4291:61: required from 'std::string std::format(format_string<_Args ...>, _Args&& ...) [with _Args = {_Float128}; string = __cxx11::basic_string<char>; format_string<_Args ...> = basic_format_string<char, _Float128>]' 4291 | { return std::vformat(__fmt.get(), std::make_format_args(__args...)); } | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ float128.cc:7:27: required from here 7 | std::cout << std::format("{}", std::float128_t{1.0}) << '\n'; | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:3277:7: note: candidate: 'std::basic_format_arg<_Context>::basic_format_arg() [with _Context = std::basic_format_context<std::__format::_Sink_iter<char>, char>]' 3277 | basic_format_arg() noexcept : _M_type(__format::_Arg_none) { } | ^~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:3277:7: note: candidate expects 0 arguments, 1 provided /opt/local/include/gcc14/c++/format:3220:11: note: candidate: 'constexpr std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::basic_format_arg(const std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >&)' 3220 | class basic_format_arg | ^~~~~~~~~~~~~~~~ /opt/local/include/gcc14/c++/format:3220:11: note: no known conversion for argument 1 from '_Float128' to 'const std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >&' /opt/local/include/gcc14/c++/format:3220:11: note: candidate: 'constexpr std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >::basic_format_arg(std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >&&)' /opt/local/include/gcc14/c++/format:3220:11: note: no known conversion for argument 1 from '_Float128' to 'std::basic_format_arg<std::basic_format_context<std::__format::_Sink_iter<char>, char> >&&' ----