Search code examples
c++stringparsingdouble

C++ convert counted char const * data to double without using std::from_chars


This problem is a programming issue, even though it is specific to the Raspberry Pi. If the community thinks I should move this to the Pi specific Stack Exchange I can do so.

That said, the root cause of the problem is caused by what appears to be a failure to support non-integer types when using std::from_chars() with gcc on the Pi. The following mcve shows the problem:

#include <charconv>

int main()
{
    char const *str = "1.23";
    int i = 0;
    std::from_chars_result result = std::from_chars(str, str + 4, i);
    double d = 0.0;
    result = std::from_chars(str, str + 4, d);
    return 0;
}

This compiles fine using MSVC on Windows 10, but generates the following error when I try with gcc gcc (Raspbian 8.3.0-6+rpi1) 8.3.0 on the Pi, it's running buster-lite if it makes a difference.

g++ -c -std=c++17 check.c
check.c: In function ‘int main()’:
check.c:9:45: error: no matching function for call to ‘from_chars(const char*&, const char*, double&)’
     result = std::from_chars(str, str + 4, d);

The reason std::from_chars is such a natural choice is that in the production version, I'm working with a std::string_view and therefore do not have any guarantees that the data is NUL-terminated. Therefore something like strtod() could potentially walk off the end of the data, and produce (best case) a misparse or (worst case) a program crash.

What other options do I have, if any?


Solution

  • Options (off the top of my head; there are definitely others):

    • Use a more modern version of gcc (specifically, a more modern libstdc++).
    • copy the data into a std::string and then call strtod on the result of calling c_str on that string (which provides a null terminator).
    • Manually copy the data into some array, and stuff a null at the end of it, then call strtod.