• dgrunwald 4 hours ago

    Caution with these functions: in most cases you need to check not only the error code, but also the `ptr` in the result. Otherwise you end up with `to_int("0x1234") == 0` instead of the expected `std::nullopt`, because these functions return success if they matched a number at the beginning of the string.

    • captainmuon 4 hours ago

      I wonder why it is called `from_chars` and not `to_number` or similar. It's obvious what you are converting from, because you have to write down the argument `from_chars(someString)`, but you don't see what is coming out.

      • Someone 30 minutes ago

        As you indicate, you do see what you’re putting in, and that includes an argument holding a reference to the result of the conversion.

        What’s coming out is a std::from_chars_result: a status code plus an indicator how much of the data was consumed.

        What to name this depends on how you see this function. As part of a function on number types, from_chars is a good names. As part of a function on strings, to_int/to_long/etc are good names. As freestanding functions, chars_to_int (ugly, IMO), parse_int (with parse sort-of implying taking a string) are options.

        I can see why they went for from_chars. Implementations will be more dependent on the output type than on character pointers, it’s more likely there will be more integral types in the future than that there will be a different way to specify character sequences, and it means adding a single function name.

        • pavlov 20 minutes ago

          Maybe “number” is too ambiguous because they’d have to define that “in this context a number means a float or integer type only.” The C++ standard also includes support for complex numbers.

        • userbinator 4 hours ago

          Wasn’t the old stuff good enough? Why do we need new methods? In short: because from_chars is low-level, and offers the best possible performance.

          That sounds like marketing BS, especially when most likely these functions just call into or are implemented nearly identically to the old C functions which are already going to "offers the best possible performance".

          I did some benchmarks, and the new routines are blazing fast![...]around 4.5x faster than stoi, 2.2x faster than atoi and almost 50x faster than istringstream

          Are you sure that wasn't because the compiler decided to optimise away the function directly? I can believe it being faster than istringstream, since that has a ton of additional overhead.

          After all, the source is here if you want to look into the horse's mouth:

          https://raw.githubusercontent.com/gcc-mirror/gcc/master/libs...

          Not surprisingly, under all those layers of abstraction-hell, there's just a regular accumulation loop.

          • deeringc an hour ago

            You might want to watch this releavnt video from Stephan T. Lavavej (the Microsoft STL maintainer): https://www.youtube.com/watch?v=4P_kbF0EbZM

            • userbinator 33 minutes ago

              I don't need to listen to what someone says if I can look at the source myself.

              • secondcoming 30 minutes ago

                You profiled the code in your head?

            • dexen 27 minutes ago

              For sake of example: a "locale-aware" number conversion routine would be the worst possible choice for parsing incoming network traffic. Beyond the performance concerns, there's the significant semantic difference in number formatting across cultures. Different conventions of decimal or thousands coma easily leading to subtle data errors or even security concerns.

              Lastly, having a simple and narrowly specified conversion routines allows one to create a small sub-set of C++ standard library fit for constrained environments like embedded systems.

              • OvbiousError 3 hours ago

                I agree with some of this, and the author could've made a better case for from/to_chars:

                - Afaik stoi and friends depend on the locale, so it's not hard to believe this introduced additional overhead. The implicit locale dependency is also often very surprising.

                - std::stoi only accepts std::string as input, so you're forced to allocate a string to use it. std::from_chars does not.

                - from/to_chars don't throw. As far as I know this won't affect performance if it doesn't happen, it does mean you can use these functions in environments where exceptions are disabled.

                • deeringc an hour ago

                  There's also the new Ryu algorithm that is being used, which is probably the biggest speed up.

                  https://github.com/ulfjack/ryu

                • eptcyka 2 hours ago

                  Locale env stuff is inherently thread unsafe, which is the main reason to never rely on it.

                • ftrobro 2 hours ago

                  Integers are simple to parse, but from_chars is a great improvement when parsing floats. It's more standardized on different platforms than the old solutions (no need to worry about the locale, for example whether to use comma or dot as decimals separator) but also has more reliable performance in different compilers. The most advanced approaches to parsing floats can be surprisingly much faster than intermediately advanced approaches. The library used by GCC since version 12 (and also used by Chrome) claims to be 4 - 10 times faster than old strtod implementations:

                  https://github.com/fastfloat/fast_float

                  For more historical context:

                  https://lemire.me/blog/2020/03/10/fast-float-parsing-in-prac...

                  • flqn an hour ago

                    They're locale independent, which the C stol, stof, etc functions are not.

                    • majoe 2 hours ago

                      A few months ago I optimized the parsing of a file and did some micro benchmarks. I observed a similar speed-up compared to stoi and atoi (didn't bother to look at stringstream). Others already commented, that it's probably due to not supporting locales.

                      • blux 3 hours ago

                        Did you verify their claims or are you just calling BS and that's it? The new functions are in fact much faster than their C equivalent (and yes, I did verify that).

                        • userbinator 2 hours ago

                          Care to explain and show the details?

                          "Extraordinary claims require extraordinary evidence."

                        • j16sdiz 3 hours ago

                          Enabling new static optimization is a good, no?

                          • halayli 31 minutes ago

                            youre answer shows dunning-kruger is full effect.

                          • cherryteastain 4 hours ago

                            Wish they returned std::expected<T, std::errc> instead of the weird from_chars_result struct

                            • Longhanks 3 hours ago

                              std::expected is new in C++23, std::from_chars was introduces in C++17. Obviously, 2023 features were not available in 2017. Changing the return type now would break everybody's code, with very little benefit, you can easily wrap std::from_chars.

                              • eMSF 3 hours ago

                                from_chars_result closely matches the strtol line of functions we've had for decades. Not returning the end position would be weird here!

                              • lynx23 5 hours ago

                                Whoever introduced the rule to automatically delete :: in titles on a hacker site should be made to rethink their decisions. Its a silly rule. It should go.

                                • pjmlp 31 minutes ago

                                  Most of those silly rules can be overriden after submission, there is a timeout to enforce the desired title instead by editing it.

                                  • MathMonkeyMan 5 hours ago

                                    It would be an interesting piece to learn why.

                                    Maybe it was for ::reasons::.

                                    • lynx23 4 hours ago

                                      I am sure the intern who wrote a rule for the Apple VoiceOver speech synthesizer to special case the number 18 being pronounced english while the synth voice is set to german imagined to have a good reason at the time as well. However, that desn't make ther decision less stupid. "Vierzehn Uhr", "Fünfzehn Uhr", "Sechzehn Uhr", "Siebzehn Uhr", "Eighteen Uhr".

                                  • einpoklum 4 hours ago

                                    Note that this won't work (AFAICT) with Unicode strings and non-western-arabic digits, e.g.:

                                        std::u8string_view chars{ u8"۱۲۳٤" };
                                        int value;
                                        enum { digit_base = 10 };
                                        auto [ptr, ec] = std::from_chars(
                                           chars.data(), chars.data() + chars.size(), value, digit_base);
                                        return (ec == std::errc{}) ? value : -1;
                                    
                                    will fail to compile due to pointer incompatibility.
                                    • cout 4 hours ago

                                      What would you suggest instead?