No portable way to detect string-to-float conversion errors in standard C
Problem
Standard C's strtod and related functions have fundamental deficiencies in error detection, locale compatibility, and edge-case handling, making it difficult for developers to reliably parse strings to floating-point numbers in a portable manner. Multiple comments highlight locale dependency, unreliable errno mechanisms, ERANGE marking for denormal values, and the lack of a two-value return API, prompting adoption of std::from_chars or third-party libraries.
Pain points
- Locale-dependent parsing: Parsing numbers assuming a decimal point breaks on systems with different locales (e.g., comma as decimal separator), causing bugs when the developer's locale differs from the target system.
- Unreliable error reporting: The return value and errno mechanism are unreliable, forcing developers to either adopt a 'don't care' approach or manually check global state, with missing API design for clean error handling.
- Denormal/underflow edge cases: strtod sets ERANGE for denormal values that are legitimate round-trip strings, but inconsistent implementations return 0.0, preventing reliable string-to-float-to-string conversion.
- Lack of convenient two-value return: Standard C cannot elegantly return both the parsed result and error status, forcing developers into outdated errno patterns or outright error ignoring.
Questions to verify
- Have you encountered locale-related parsing failures in production or cross-system data processing?
- Would a portable error-reporting conversion library improve your development experience?
- Are you currently adopting std::from_chars or third-party solutions, or still reliant on standard C functions?
Evidence
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.
[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.
Denormals therefore count as underflow and strtod() sets ERANGE for them, even though they they are legitimate values to store as strings and parse back. Some implementations of strtod() return the correct floating-point value for these, while setting ERANGE. Others discard the value and return 0.0, preventing them from being round-tripped to strings.
When I was writing some ASM for a microcontroller to do string <--> float conversion, I could find almost nothing on how to best perform the operations. There were essentially three ways to do it. Muddle through with a naive implementation. Look at the ASM of an old 8-bit machine. The final category was the by far the most dominant suggestion, to the point that anything else is almost like lost knowledge now. That solution was to use the C standard functions. It seems like this is a sufficiently unpleasant task that as soon as anyone didn't absolutely have to do it all themselves, the punted to a black box solution.
Disclaimer: this card is distilled by AI from community discussions as “pain point evidence”. It is a starting point for need analysis and validation, not a “validated market need”. AI has analytical limits; please open the original discussion above to manually verify before key decisions.