C's strtod Can't Portably Detect Conversion Errors, and the Standard Is to Blame

No portable way to detect string-to-float conversion errors in standard C

The C standard ties strtod's error reporting to math_errhandling, so on libcs like musl that don't support errno, overflow and underflow go unreported. POSIX mandates errno=ERANGE, but that may violate the C standard. For malformed input, glibc leaves errno at 0 while musl sets EINVAL—undocumented and nonconformant. The only portable check is endptr == nptr, and underflow detection is essentially impossible.

musl, on the other hand, does set errno to EINVAL, so this prints "22". This is completely undocumented on the linux man page. it's also, from my reading of the standard, not conformant to standard c, because it's setting errno to a nonzero value in a function with other documented error conditions (and as far as standard c is concerned, invalid input isn't an error condition).
  1. Joker_vD

    It's quite astonishing how the historical inability of commonly used programming languages (from FORTRAN all the way to, say, Java/C#) to ergonomically return two values from a function call has caused people to invent all kinds of insane APIs/contracts.

    [double x, errno_t errno] = strtod(s, nullptr);

    if (errno != 0) {

    // ...

    }

    [x, _] = strtod(s, nullptr); // When you're certain the error is impossible or just don't care

    Instead, we're stuck with "check if the return value is -1 and if it is, check the global variable errno" at best, and with "the function doesn't really reliably reports its errors so don't feed it malformed data, idc" at worst.

  2. Panzerschrek

    C number parsing functions are fundamentally broken, since they are locale-dependend. There are many bugs when one parses a number assuming it has decimal point, but later on systems with locale different from one used on developer's machine it may be suddenly comma instead of point. So, one should avoid using them almost always and use std::from_chars (available in new C++ versions) or some other thirdparty library.

  3. gucci-on-fleek

    > the linux man pages for these functions literally don't mention this at all

    > the fact that the man page never makes any note of this being an extension ([…]) is really notable to me.

    > this is completely undocumented on the linux man page.

    The Linux man page maintainers are really friendly in my experience, so it's probably worth reporting this to them [0] [1].

    [0]: https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/...

    [1]: https://lore.kernel.org/linux-man/

  4. RossBencina

    For a long time Microsoft's strtod implementation was broken, I'd think most people would be using netlib or one of the newer algorithms.

    https://www.exploringbinary.com/visual-c-plus-plus-strtod-st...

    https://lemire.me/blog/2026/02/01/converting-floats-to-strin...

  5. chasil

    IEEE-754 is a harsh mistress.

    https://en.wikipedia.org/wiki/IEEE_754

More from this day

2026-10-12