https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110143
Bug ID: 110143 Summary: std::format for pointer arguments does not work Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: bruno at clisp dot org Target Milestone: --- Created attachment 55272 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55272&action=edit test case bug1.cc The C++20 <format> facility (n4861.pdf section 20.20.2.2 paragraph 23 specifies that pointers should be printable through std::format, either with no type specifier, or with the type specifier 'p'. Neither of these works with GCC 13.1.0. How to reproduce: Use the attached bug1.c and bug2.c files. $ g++ -Wall -std=gnu++20 bug1.cc In file included from bug1.cc:1: /inst-gcc/13.1.0/include/c++/13.1.0/format: In instantiation of ‘class std::__format::_Checking_scanner<char, int*>’: /inst-gcc/13.1.0/include/c++/13.1.0/format:3642:4: required from ‘consteval std::basic_format_string<_CharT, _Args>::basic_format_string(const _Tp&) [with _Tp = char [4]; _CharT = char; _Args = {int*}]’ bug1.cc:11:27: required from here /inst-gcc/13.1.0/include/c++/13.1.0/format:3564:10: error: static assertion failed: std::formatter must be specialized for each type being formatted 3564 | (is_default_constructible_v<formatter<_Args, _CharT>> && ...), | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /inst-gcc/13.1.0/include/c++/13.1.0/format:3564:10: note: ‘std::is_default_constructible_v<std::formatter<int*, char> >’ evaluates to false /inst-gcc/13.1.0/include/c++/13.1.0/format: In instantiation of ‘constexpr void std::__format::_Checking_scanner<_CharT, _Args>::_M_parse_format_spec(std::size_t) [with _Tp = int*; _OtherArgs = {}; _CharT = char; _Args = {int*}; std::size_t = long unsigned int]’: /inst-gcc/13.1.0/include/c++/13.1.0/format:3581:33: required from here bug1.cc:11:27: in ‘constexpr’ expansion of ‘std::basic_format_string<char, int*>("{:}")’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3643:19: in ‘constexpr’ expansion of ‘__scanner.std::__format::_Checking_scanner<char, int*>::<anonymous>.std::__format::_Scanner<char>::_M_scan()’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3453:30: in ‘constexpr’ expansion of ‘((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_on_replacement_field()’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3505:15: in ‘constexpr’ expansion of ‘((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_format_arg(__id)’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3594:38: error: use of deleted function ‘std::formatter<_Tp, _CharT>::formatter() [with _Tp = int*; _CharT = char]’ 3594 | formatter<_Tp, _CharT> __f; | ^~~ /inst-gcc/13.1.0/include/c++/13.1.0/format:140:7: note: declared here 140 | formatter() = delete; // No std::formatter specialization for this type. | ^~~~~~~~~ /inst-gcc/13.1.0/include/c++/13.1.0/format:3595:42: error: ‘struct std::formatter<int*, char>’ has no member named ‘parse’ 3595 | this->_M_pc.advance_to(__f.parse(this->_M_pc)); | ~~~~^~~~~ $ g++ -Wall -std=gnu++20 bug2.cc In file included from bug2.cc:1: /inst-gcc/13.1.0/include/c++/13.1.0/format: In instantiation of ‘class std::__format::_Checking_scanner<char, int*>’: /inst-gcc/13.1.0/include/c++/13.1.0/format:3642:4: required from ‘consteval std::basic_format_string<_CharT, _Args>::basic_format_string(const _Tp&) [with _Tp = char [5]; _CharT = char; _Args = {int*}]’ bug2.cc:11:27: required from here /inst-gcc/13.1.0/include/c++/13.1.0/format:3564:10: error: static assertion failed: std::formatter must be specialized for each type being formatted 3564 | (is_default_constructible_v<formatter<_Args, _CharT>> && ...), | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /inst-gcc/13.1.0/include/c++/13.1.0/format:3564:10: note: ‘std::is_default_constructible_v<std::formatter<int*, char> >’ evaluates to false /inst-gcc/13.1.0/include/c++/13.1.0/format: In instantiation of ‘constexpr void std::__format::_Checking_scanner<_CharT, _Args>::_M_parse_format_spec(std::size_t) [with _Tp = int*; _OtherArgs = {}; _CharT = char; _Args = {int*}; std::size_t = long unsigned int]’: /inst-gcc/13.1.0/include/c++/13.1.0/format:3581:33: required from here bug2.cc:11:27: in ‘constexpr’ expansion of ‘std::basic_format_string<char, int*>("{:p}")’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3643:19: in ‘constexpr’ expansion of ‘__scanner.std::__format::_Checking_scanner<char, int*>::<anonymous>.std::__format::_Scanner<char>::_M_scan()’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3453:30: in ‘constexpr’ expansion of ‘((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_on_replacement_field()’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3505:15: in ‘constexpr’ expansion of ‘((std::__format::_Scanner<char>*)this)->std::__format::_Scanner<char>::_M_format_arg(__id)’ /inst-gcc/13.1.0/include/c++/13.1.0/format:3594:38: error: use of deleted function ‘std::formatter<_Tp, _CharT>::formatter() [with _Tp = int*; _CharT = char]’ 3594 | formatter<_Tp, _CharT> __f; | ^~~ /inst-gcc/13.1.0/include/c++/13.1.0/format:140:7: note: declared here 140 | formatter() = delete; // No std::formatter specialization for this type. | ^~~~~~~~~ /inst-gcc/13.1.0/include/c++/13.1.0/format:3595:42: error: ‘struct std::formatter<int*, char>’ has no member named ‘parse’ 3595 | this->_M_pc.advance_to(__f.parse(this->_M_pc)); | ~~~~^~~~~