[static_string] Desired behavior of to_static_[w]string() for floating point values
Hi everyone, I'd like to gather your input on the desired behavior of to_static_string() and to_static_wstring() when formatting floating point values. Currently, both functions mimic std::to_string() / std::to_wstring() as long as the result fits within the static string's capacity. If not, they fall back to scientific notation. However, C++26 introduces a breaking change: std::to_string() and std::to_wstring() will behave as if implemented via std::format() rather than s[w]printf(). For example, std::to_string( 0.1 ) will yield "0.1" instead of "0.100000". Given this shift, what behavior would you prefer for to_static_[w]string()? a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26. b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions. c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change). d) Other. Please let me know what you think. Thanks. -- Gennaro Prota <https://prota.dev>
Am 07.10.25 um 10:15 schrieb Gennaro Prota via Boost:
Given this shift, what behavior would you prefer for to_static_[w]string()?
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
I'd go with option a) I think for users it is reasonable to expect `std::to_string(value) == boost::to_static_string(value)` holds, even though it can cause confusion when changing standard modes. However this allows to (gradually) use boost::static_string as a drop-in for std::string without causing breakages
Gennaro Prota wrote:
Hi everyone,
I'd like to gather your input on the desired behavior of to_static_string() and to_static_wstring() when formatting floating point values.
Currently, both functions mimic std::to_string() / std::to_wstring() as long as the result fits within the static string's capacity. If not, they fall back to scientific notation.
However, C++26 introduces a breaking change: std::to_string() and std::to_wstring() will behave as if implemented via std::format() rather than s[w]printf(). For example, std::to_string( 0.1 ) will yield "0.1" instead of "0.100000".
Given this shift, what behavior would you prefer for to_static_[w]string()?
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Please let me know what you think.
c)
I favour option c. I implemented my own static_string class which is also usable on ancient compilers. This is my comment for the to_fc_string function: // Conversion double/float => fc_string is not completely standard. // Before C++20 this is defined as using %f which requires more than // 300 bytes to store // C++20 makes this more reasonable so do not rely to much on the // exact result of this conversion for very small or large values // Please note that the standard formats a float as a double. // We currently save space and only store significant digits of both // types. If I remember correctly this will not always give the exact same result as C++20, but is it good enough. And the actual implementation is basically sprintf(res,"%0.17g",value) for double. /Peter On Tue, Oct 7, 2025 at 10:16 AM Gennaro Prota via Boost < boost@lists.boost.org> wrote:
Hi everyone,
I'd like to gather your input on the desired behavior of to_static_string() and to_static_wstring() when formatting floating point values.
Currently, both functions mimic std::to_string() / std::to_wstring() as long as the result fits within the static string's capacity. If not, they fall back to scientific notation.
However, C++26 introduces a breaking change: std::to_string() and std::to_wstring() will behave as if implemented via std::format() rather than s[w]printf(). For example, std::to_string( 0.1 ) will yield "0.1" instead of "0.100000".
Given this shift, what behavior would you prefer for to_static_[w]string()?
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Please let me know what you think.
Thanks.
-- Gennaro Prota <https://prota.dev>
_______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/LMTGWPUG...
On October 7, 2025 11:15:36 AM Gennaro Prota via Boost <boost@lists.boost.org> wrote:
Hi everyone,
I'd like to gather your input on the desired behavior of to_static_string() and to_static_wstring() when formatting floating point values.
Currently, both functions mimic std::to_string() / std::to_wstring() as long as the result fits within the static string's capacity. If not, they fall back to scientific notation.
However, C++26 introduces a breaking change: std::to_string() and std::to_wstring() will behave as if implemented via std::format() rather than s[w]printf(). For example, std::to_string( 0.1 ) will yield "0.1" instead of "0.100000".
Given this shift, what behavior would you prefer for to_static_[w]string()?
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Please let me know what you think.
Any to_(whatever_)string functions should produce the same result, regardless of the standard version. Otherwise, you'd be laying landmines to users. Better break users once than keep them breaking themselves all the time. So option c.
On Tue, Oct 7, 2025, at 5:19 PM, Andrey Semashev via Boost wrote:
Please let me know what you think.
Any to_(whatever_)string functions should produce the same result, regardless of the standard version. Otherwise, you'd be laying landmines to users. Better break users once than keep them breaking themselves all the time. So option c.
Hmm. Did I get this right? Because I completely agree with reasoning, however, that means I expected you to strongly assert option a. - Note that option c means that `to_static_string` may NOT produce the same as `to_string`. - Also, indeed: better to break users *once*. Meaning, when they switch to c++26 compilation (it seems this breakage cannot be avoided since it's part of standard specification?) Seth
On October 7, 2025 7:28:27 PM Seth <bugs@sehe.nl> wrote:
On Tue, Oct 7, 2025, at 5:19 PM, Andrey Semashev via Boost wrote:
Please let me know what you think.
Any to_(whatever_)string functions should produce the same result, regardless of the standard version. Otherwise, you'd be laying landmines to users. Better break users once than keep them breaking themselves all the time. So option c.
Hmm. Did I get this right? Because I completely agree with reasoning, however, that means I expected you to strongly assert option a.
- Note that option c means that `to_static_string` may NOT produce the same as `to_string`. - Also, indeed: better to break users *once*. Meaning, when they switch to c++26 compilation (it seems this breakage cannot be avoided since it's part of standard specification?)
No. My opinion is to_string and to_static_string should return the same string, at any supported C++ version. Option a doesn't qualify the second part.
On October 7, 2025 8:39:16 PM Andrey Semashev <andrey.semashev@gmail.com> wrote:
On October 7, 2025 7:28:27 PM Seth <bugs@sehe.nl> wrote:
On Tue, Oct 7, 2025, at 5:19 PM, Andrey Semashev via Boost wrote:
Please let me know what you think.
Any to_(whatever_)string functions should produce the same result, regardless of the standard version. Otherwise, you'd be laying landmines to users. Better break users once than keep them breaking themselves all the time. So option c.
Hmm. Did I get this right? Because I completely agree with reasoning, however, that means I expected you to strongly assert option a.
- Note that option c means that `to_static_string` may NOT produce the same as `to_string`. - Also, indeed: better to break users *once*. Meaning, when they switch to c++26 compilation (it seems this breakage cannot be avoided since it's part of standard specification?)
No. My opinion is to_string and to_static_string should return the same string, at any supported C++ version. Option a doesn't qualify the second part.
"at any supported C++ version" here means that for a given input the produced output string should be the same at any supported C++ version.
For (a) we sacrifice consistency between C++ versions where for (c) we sacrifice consistency with the standard library. Neither option is ideal. I think, on balance, consistency with the standard library is more important than consistency between C++ versions. Users will expect static_string to behave consistently with std::string, particularly if writing generic code, which means to_*_string functions behaving consistently. When changing C++ versions users are going to have to deal with the to_string behaviour change anyway so to_static_string behaviour changes won’t be too much of a surprise. For the record I was *not* a fan of WG21 changing the behaviour of to_string but that ship has sailed. On 7 Oct 2025, at 18:43, Andrey Semashev via Boost <boost@lists.boost.org> wrote: On October 7, 2025 8:39:16 PM Andrey Semashev <andrey.semashev@gmail.com> wrote:
On October 7, 2025 7:28:27 PM Seth <bugs@sehe.nl> wrote:
On Tue, Oct 7, 2025, at 5:19 PM, Andrey Semashev via Boost wrote:
Please let me know what you think.
Any to_(whatever_)string functions should produce the same result, regardless of the standard version. Otherwise, you'd be laying landmines to users. Better break users once than keep them breaking themselves all the time. So option c.
Hmm. Did I get this right? Because I completely agree with reasoning, however, that means I expected you to strongly assert option a.
- Note that option c means that `to_static_string` may NOT produce the same as `to_string`. - Also, indeed: better to break users *once*. Meaning, when they switch to c++26 compilation (it seems this breakage cannot be avoided since it's part of standard specification?)
No. My opinion is to_string and to_static_string should return the same string, at any supported C++ version. Option a doesn't qualify the second part.
"at any supported C++ version" here means that for a given input the produced output string should be the same at any supported C++ version. _______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/OXAG4DU4...
On 7 Oct 2025 23:46, Mungo Gill wrote:
For (a) we sacrifice consistency between C++ versions where for (c) we sacrifice consistency with the standard library. Neither option is ideal.
I think, on balance, consistency with the standard library is more important than consistency between C++ versions. Users will expect static_string to behave consistently with std::string, particularly if writing generic code, which means to_*_string functions behaving consistently.
When changing C++ versions users are going to have to deal with the to_string behaviour change anyway so to_static_string behaviour changes won’t be too much of a surprise.
For the record I was *not* a fan of WG21 changing the behaviour of to_string but that ship has sailed.
As a Boost library we can do better than copying std flaws. Users of Boost should (and, IMHO, are) prepared that Boost and std components may differ in some ways, and in fact it is these differences that may be the reason they choose one or the other. If we know we want one behavior over the other, I don't see conformance with std as a compelling factor to choose the less preferable solution.
On Tue, Oct 7, 2025, at 7:41 PM, Andrey Semashev wrote:
No. My opinion is to_string and to_static_string should return the same string, at any supported C++ version. Option a doesn't qualify the second part.
"at any supported C++ version" here means that for a given input the produced output string should be the same at any supported C++ version.
Thanks for clarifying. I think we agree 100% on the goals. One of us reading the options wrong though, because I felt it is clearly the other way around. Regardless of who is right here, let's just keep in mind that confusion seems to be possible and re-check whether the options as posed are unambiguous for the rest of us. When I did that exercise, it occurred to me that `to_string` vs. `to_static_string` implies `std::to_string` vs. `boost::to_static_string` always (TTBOMK boost doesn't implement `to_string` except for non-standard types or as member function?). With that in mind, option (a) is clearly what will (quoting your requirement): "make to_string and to_static_string [should] return the same string, at any supported C++ version" (AT any version; not BETWEEN versions, but there's no way to achieve that for `std::to_string` no matter what) Seth
On 8 Oct 2025 00:30, Seth via Boost wrote:
On Tue, Oct 7, 2025, at 7:41 PM, Andrey Semashev wrote:
No. My opinion is to_string and to_static_string should return the same string, at any supported C++ version. Option a doesn't qualify the second part.
"at any supported C++ version" here means that for a given input the produced output string should be the same at any supported C++ version.
Thanks for clarifying. I think we agree 100% on the goals. One of us reading the options wrong though, because I felt it is clearly the other way around.
Regardless of who is right here, let's just keep in mind that confusion seems to be possible and re-check whether the options as posed are unambiguous for the rest of us.
When I did that exercise, it occurred to me that `to_string` vs. `to_static_string` implies `std::to_string` vs. `boost::to_static_string` always (TTBOMK boost doesn't implement `to_string` except for non-standard types or as member function?).
With that in mind, option (a) is clearly what will (quoting your requirement): "make to_string and to_static_string [should] return the same string, at any supported C++ version" (AT any version; not BETWEEN versions, but there's no way to achieve that for `std::to_string` no matter what)
Re-reading the original post now, I think I see that I was somehow confused. I thought there was a Boost equivalent of to_string and also to_static_string, and we were considering how to align them with std::to_string. I was choosing option c from the standpoint of keeping the (supposed) boost::to_string and boost::to_static_string behaviors consistent and independent of the C++ version used. Speaking of just boost::to_static_string, I would still choose option c because that seems like the better behavior and I still consider independence of the C++ version the more desirable option.
On Tue, 7 Oct 2025 at 10:17, Gennaro Prota via Boost <boost@lists.boost.org> wrote:
Hi everyone,
I'd like to gather your input on the desired behavior of to_static_string() and to_static_wstring() when formatting floating point values.
Currently, both functions mimic std::to_string() / std::to_wstring() as long as the result fits within the static string's capacity. If not, they fall back to scientific notation.
However, C++26 introduces a breaking change: std::to_string() and std::to_wstring() will behave as if implemented via std::format() rather than s[w]printf(). For example, std::to_string( 0.1 ) will yield "0.1" instead of "0.100000".
Given this shift, what behavior would you prefer for to_static_[w]string()?
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Please let me know what you think.
Thanks.
c). Better break them once, and std::to_string is already surprising in older standards as to replicate it.
-- Gennaro Prota <https://prota.dev>
_______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/LMTGWPUG...
On 10/7/2025 10:15 AM, Gennaro Prota wrote: [...]
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
Thanks everyone for your input. It seems that c) is the winner. There's a problem though: I imagined implementing it using Boost.Charconv, but that only supports char, not wchar_t. Any idea on how to implement it for wchar_t without making it totally inefficient? -- Gennaro Prota <https://prota.dev>
On 10/7/2025 10:15 AM, Gennaro Prota wrote:
Hi everyone,
I'd like to gather your input on the desired behavior of to_static_string() and to_static_wstring() when formatting floating point values.
Currently, both functions mimic std::to_string() / std::to_wstring() as long as the result fits within the static string's capacity. If not, they fall back to scientific notation.
However, C++26 introduces a breaking change: std::to_string() and std::to_wstring() will behave as if implemented via std::format() rather than s[w]printf(). For example, std::to_string( 0.1 ) will yield "0.1" instead of "0.100000".
Given this shift, what behavior would you prefer for to_static_[w]string()?
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Please let me know what you think.
Thanks.
Although my preference was for c), too, I ultimately went with a), because the former would have required to basically reimplement std::format() inside StaticString, which felt like a bit of overkill :-). If there aren't any objections, I'll merge the changes into master, in time for Boost 1.90. -- Gennaro Prota <https://prota.dev>
Am 22.10.25 um 16:52 schrieb Gennaro Prota via Boost:
On 10/7/2025 10:15 AM, Gennaro Prota wrote:
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Although my preference was for c), too, I ultimately went with a), because the former would have required to basically reimplement std::format() inside StaticString, which felt like a bit of overkill :-). If there aren't any objections, I'll merge the changes into master, in time for Boost 1.90.
IIRC c) is basically what `to_chars` does. So if using Boost.Charconv for pre-C++17 would allow that. This way you don't need to implement anything by yourself. Am I missing anything or did you want to avoid that dependency?
On 10/22/2025 5:29 PM, Alexander Grund via Boost wrote:
Am 22.10.25 um 16:52 schrieb Gennaro Prota via Boost:
On 10/7/2025 10:15 AM, Gennaro Prota wrote:
a) Match std::to_[w]string() and adopt the new behavior when compiling under C++26.
b) Preserve the legacy behavior with fixed precision (6 digits) across all standard versions.
c) Always behave as if using std::format(), even in pre-C++26 builds (breaking change).
d) Other.
Although my preference was for c), too, I ultimately went with a), because the former would have required to basically reimplement std::format() inside StaticString, which felt like a bit of overkill :-). If there aren't any objections, I'll merge the changes into master, in time for Boost 1.90.
IIRC c) is basically what `to_chars` does. So if using Boost.Charconv for pre-C++17 would allow that. This way you don't need to implement anything by yourself. Am I missing anything or did you want to avoid that dependency?
Yes, that would mean having a header-only library (StaticString) depend on a compiled one (Charconv). -- Gennaro Prota <https://prota.dev>
participants (8)
-
Alexander Grund -
Andrey Semashev -
Gennaro Prota -
Mungo Gill -
Peter Dimov -
Peter Koch Larsen -
Ruben Perez -
Seth