[PATCH] libstdc++: Export explicit instantiations of __format::__do_vformat_to.
Tomasz Kaminski
tkaminsk@redhat.com
Fri Apr 3 11:49:50 GMT 2026
On Fri, Apr 3, 2026 at 1:48 PM Tomasz Kamiński <tkaminsk@redhat.com> wrote:
> This patch exports instantiations of __format::__do_vformat_to
> for _Sink_iter and char/wchar_t. As every format function is
> implementing as delegating the one of these overloads, this
> significantly reduces the compliation time.
>
> Instantiating __format::__do_vformat_to triggers specializations
> of formatters for types stored in handle direclty (arithmetic
> types, strings), however we do not export any of their symbols.
> This keeps the interface boundary minimal. This file should
> be recompiled in later mode, when it is called stable.
>
> libstdc++-v3/ChangeLog:
>
> * config/abi/pre/gnu.ver (GLIBCXX_3.4): Exclude exports
> of std::basic_fo* (matching basic_format_context).
> (GLIBCXX_3.4.35): Export __format::__do_vformat_to
> specializations for _Sink_iter and char/wchar_t.
> * include/std/format: (__format::__do_vformat_to):
> Remove inline and declare extern instantiation
> of __format::__do_vformat_to _Sink_iter and char/wchar_t.
> * src/c++20/Makefile.am: Add format-inst.cc.
> * src/c++20/Makefile.in: Regenerate.
> * src/c++20/format-inst.cc: New file defining explicit
> instantiation.
> ---
> From simple test on files from testsuite/std/format/functions/, the
> results looks very promising:
>
> Before After
> format.cc 24.203s 10.846s
> format_to.cc 18.475s 2.844s
> format_to_n.cc 18.677s 3.074s
> vformat_to.cc 17.281s 2.246s
>
> However, I am a bit concerned if the approach works, as
> libstdc++.so will always contains weak simbol for __do_vformat_to
> for _Sink_iter<char>, that supports only C++20 specifiers.
> Should we instead compile the format-inst in latest mode, and
> always provide extern defintion?
> Note that the same problem will also be present for the print function,
> but I haven not realized it then.
>
The scenarios like that are not only teoreticall, debug support (?) for
string and char was recently added.
>
> I plan to do similar change for __formatter_chrono<char>::_M_format
> functions (entry point).
>
>
> libstdc++-v3/config/abi/pre/gnu.ver | 8 ++++-
> libstdc++-v3/include/std/format | 13 +++++++-
> libstdc++-v3/src/c++20/Makefile.am | 3 +-
> libstdc++-v3/src/c++20/Makefile.in | 6 ++--
> libstdc++-v3/src/c++20/format-inst.cc | 46 +++++++++++++++++++++++++++
> 5 files changed, 71 insertions(+), 5 deletions(-)
> create mode 100644 libstdc++-v3/src/c++20/format-inst.cc
>
> diff --git a/libstdc++-v3/config/abi/pre/gnu.ver
> b/libstdc++-v3/config/abi/pre/gnu.ver
> index fb968e122d8..2b391584c94 100644
> --- a/libstdc++-v3/config/abi/pre/gnu.ver
> +++ b/libstdc++-v3/config/abi/pre/gnu.ver
> @@ -34,7 +34,9 @@ GLIBCXX_3.4 {
> std::basic_[a-e]*;
> std::basic_f[a-h]*;
> # std::basic_filebuf;
> - std::basic_f[j-r]*;
> + std::basic_f[j-n]*;
> +# std::basic_format_context;
> + std::basic_f[p-r]*;
> # std::basic_fstream;
> std::basic_f[t-z]*;
> std::basic_[g-h]*;
> @@ -2587,6 +2589,10 @@ GLIBCXX_3.4.35 {
> _ZNSt12__cow_stringaSEOS_;
> _ZNKSt12__cow_string5c_strEv;
>
> + # __format::__do_vformat_to(_Sink_iter<char>, string_view, const
> format_args&, const locale*);
> + # __format::__do_vformat_to(_Sink_iter<wchar_t>, wstring_view, const
> wformat_args&, const locale*);
> +
> _ZNSt8__format15__do_vformat_toINS_10_Sink_iterI[wc]EE[wc]St20basic_format_contextIS2_[wc]EEET_S5_St17basic_string_viewIT0_St11char_traitsIS7_EERKSt17basic_format_argsIT1_EPKSt6locale;
> +
> #if defined (_WIN32) && !defined (__CYGWIN__)
> _ZSt19__get_once_callablev;
> _ZSt15__get_once_callv;
> diff --git a/libstdc++-v3/include/std/format
> b/libstdc++-v3/include/std/format
> index eca5bd213aa..2a8229a2eb5 100644
> --- a/libstdc++-v3/include/std/format
> +++ b/libstdc++-v3/include/std/format
> @@ -5220,7 +5220,7 @@ namespace __format
> };
>
> template<typename _Out, typename _CharT, typename _Context>
> - inline _Out
> + _Out
> __do_vformat_to(_Out __out, basic_string_view<_CharT> __fmt,
> const basic_format_args<_Context>& __args,
> const locale* __loc)
> @@ -5310,6 +5310,17 @@ namespace __format
> }
> }
>
> +#if __cplusplus <= 202002L && _GLIBCXX_EXTERN_TEMPLATE > 0
> + extern template _Sink_iter<char>
> + __do_vformat_to(_Sink_iter<char>, string_view,
> + const format_args&, const locale*);
> +# ifdef _GLIBCXX_USE_WCHAR_T
> + extern template _Sink_iter<wchar_t>
> + __do_vformat_to(_Sink_iter<wchar_t>, wstring_view,
> + const wformat_args&, const locale*);
> +# endif
> +#endif
> +
> template<typename _Out, typename _CharT>
> format_to_n_result<_Out>
> __do_vformat_to_n(_Out __out, iter_difference_t<_Out> __n,
> diff --git a/libstdc++-v3/src/c++20/Makefile.am
> b/libstdc++-v3/src/c++20/Makefile.am
> index 0061678dc0f..7744fa43a63 100644
> --- a/libstdc++-v3/src/c++20/Makefile.am
> +++ b/libstdc++-v3/src/c++20/Makefile.am
> @@ -30,7 +30,8 @@ headers =
> if ENABLE_EXTERN_TEMPLATE
> # XTEMPLATE_FLAGS = -fno-implicit-templates
> inst_sources = \
> - sstream-inst.cc
> + sstream-inst.cc \
> + format-inst.cc
> else
> # XTEMPLATE_FLAGS =
> inst_sources =
> diff --git a/libstdc++-v3/src/c++20/Makefile.in
> b/libstdc++-v3/src/c++20/Makefile.in
> index f481ad08edb..566d7292021 100644
> --- a/libstdc++-v3/src/c++20/Makefile.in
> +++ b/libstdc++-v3/src/c++20/Makefile.in
> @@ -124,7 +124,8 @@ CONFIG_CLEAN_VPATH_FILES =
> LTLIBRARIES = $(noinst_LTLIBRARIES)
> libc__20convenience_la_LIBADD =
> am__objects_1 = tzdb.lo format.lo atomic.lo clock.lo syncbuf.lo
> -@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo
> +@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo \
> +@ENABLE_EXTERN_TEMPLATE_TRUE@ format-inst.lo
> @GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \
> @GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2)
> libc__20convenience_la_OBJECTS = $(am_libc__20convenience_la_OBJECTS)
> @@ -433,7 +434,8 @@ headers =
>
> # XTEMPLATE_FLAGS = -fno-implicit-templates
> @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
> -@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc
> +@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc \
> +@ENABLE_EXTERN_TEMPLATE_TRUE@ format-inst.cc
>
> sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc
> @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES =
> diff --git a/libstdc++-v3/src/c++20/format-inst.cc
> b/libstdc++-v3/src/c++20/format-inst.cc
> new file mode 100644
> index 00000000000..1904de35f7b
> --- /dev/null
> +++ b/libstdc++-v3/src/c++20/format-inst.cc
> @@ -0,0 +1,46 @@
> +// Definitions for <chrono> formatting -*- C++ -*-
> +
> +// Copyright The GNU Toolchain Authors.
> +//
> +// This file is part of the GNU ISO C++ Library. This library is free
> +// software; you can redistribute it and/or modify it under the
> +// terms of the GNU General Public License as published by the
> +// Free Software Foundation; either version 3, or (at your option)
> +// any later version.
> +
> +// This library is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +// GNU General Public License for more details.
> +
> +// Under Section 7 of GPL version 3, you are granted additional
> +// permissions described in the GCC Runtime Library Exception, version
> +// 3.1, as published by the Free Software Foundation.
> +
> +// You should have received a copy of the GNU General Public License and
> +// a copy of the GCC Runtime Library Exception along with this program;
> +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> +// <http://www.gnu.org/licenses/>.
> +
> +#include <format>
> +#include <chrono>
> +
> +namespace std
> +{
> +_GLIBCXX_BEGIN_NAMESPACE_VERSION
> +namespace __format
> +{
> +
> + template _Sink_iter<char>
> + __do_vformat_to(_Sink_iter<char>, string_view,
> + const format_args&, const locale*);
> +
> +# ifdef _GLIBCXX_USE_WCHAR_T
> + template _Sink_iter<wchar_t>
> + __do_vformat_to(_Sink_iter<wchar_t>, wstring_view,
> + const wformat_args&, const locale*);
> +# endif
> +
> +} // namespace __format
> +_GLIBCXX_END_NAMESPACE_VERSION
> +} // namespace std
> --
> 2.53.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260403/193a6e7e/attachment-0001.htm>
More information about the Libstdc++
mailing list