4 ms·
> why is locale stuff even in sprintf? What things get localized Decimal places in floating point numbers is the primary standard thing (some locales use `.` a
by MaulingMonkey 5y ago
> why is locale stuff even in sprintf? What things get localized
Decimal places in floating point numbers is the primary standard thing (some locales use `.` as a decimal seperator and `,` as a thousands seperator... some locales swap interpretations!) Nonstandard extensions may also do things like accept unicode strings, wide unicode strings, etc. which may need to be re-encoded to whatever the ambient locale-specified narrow encoding is (UTF16 => windows-1251?).
In the modern era of sprintf being exiled to some low level internal thing, I agree it makes little sense - causing more bugs than it fixes - but in the days of using it for a lot of heavy lifting of user-facing data, it was an understandable target for this kind of treatment.
- butlerm 5y agoThe overhead is completely unnecessary in far too many cases. So what they should have done is kept sprintf to its traditional behavior and invented a new, slower alternative for those fairly unusual cases that need locale sensitivity. Locales tend to be all or nothing and extremely inefficient to make general use of anyway because too many things are controlled by the same setting. Standards committees should not carelessly sit down and devise things that destroy performance by a factor of ten or more, especially when it is entirely unnecessary and where they do not keep or provide simple, fast alternatives for the most common cases where the format is known and has nothing to do with a preferred locale. What they did instead was a massive energy and time wasting imposition of unhelpful semantics on functions that did not have or need any such thing instead of a tailored let's only do this in special cases with special functions approach.
- jcelerier 5y agoC++ has thankfully locale- independent functions now, std::from_chars, std::to_chars.. but it took way too many years
- gustavorg 5y agoI am very curious to know why you guys are forgetting std::to_string. It is available since c++11. This and then str.c_ctr() should make the trick in most cases.
- formerly_proven 5y agoto_string uses the locale.
- jcelerier 5y agoto_string is just a wrapper around sprintf... here's the (de-__uglyfied) code on libstdc++: inline string to_string(float val) { const int n = gnu_cxx::numeric_traits<float>::max_exponent10 + 20; return gnu_cxx::to_xstring<string>(&std::vsnprintf, n, "%f", val); } it will be worse in pretty much every metric than fmt::format("{}", val);
- MaulingMonkey 5y agosprintf/setlocale date back to at least C89, and probably even earlier - over three decades ago, this wasn't the performance and multithreading hazard it is today, because people simply weren't multithreading. Global state was the practice de jure - even reasonably so, compared to drowning everything in a sea of redundant parameterization on monochrome 80x25 terminals, in an era of smaller programs, when global state was easier to reason about. The C89 standards committee wasn't "careless" here - it was a product of the times. Of course, when modern APIs and standards committees duplicate sprintf's issues, it's far more fustrating - even when justified in the light of "backwards compatability".
- jcelerier 5y agoYeah, as a french I often have to set my LANG to C because of how many buggy apps that use sprintf without fixing a locale exist (making save files at best unshareable with the world at worse unreadable again)