https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123167

            Bug ID: 123167
           Summary: to_chars(long double) produces rubbish with
                    -mlong-double-64
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: cassio.neri at gmail dot com
  Target Milestone: ---

Let T be double or long double and x = T{1}/T{3}. Then, for x86-64 with
-mlong-double-64, successful calls to

to_chars(begin, end, x, chars_format::scientific);

produce 3.333333333333333e-01 for double and, due ABI/UB issues, for long
double the result varies across runs. I once got 5.1301514607137e-4937. (See
https://godbolt.org/z/aM9z94Kac)

The result for long double is wrong under all accounts but, more precisely, it
was expected to exactly match double's because, under -mlong-double-64, long
double is equivalent to double [1].

This is what happens. The logic to account for different long double formats is
in
src/libstdc++-v3/src/c++17/floating_to_chars.cc, particularly, in this bit:

  if constexpr (LONG_DOUBLE_KIND == LDK_BINARY64
                || LONG_DOUBLE_KIND == LDK_UNSUPPORTED)
    return __floating_to_chars_shortest(first, last,
static_cast<double>(value),
                                        fmt);
  else
    return __floating_to_chars_shortest(first, last, value, fmt);

This is correct but, the value of LONG_DOUBLE_KIND is determined when
floating_to_chars.cc is compiled. When the user changes the format, it's too
late because the binary of libstdc++ has already set in stone the format of
long double that to_chars supports.

The logic above has to be moved to a file that's compiled by the user (ie the
header charconv). Moreover, floating_to_chars.cc must, somehow, be prepared to
receive whatever long double format the user chooses.

I'm working on a fix as part of my rewrite of to_chars based on Tejú Jaguá.
I'll also include a test which will refer to this report.

[1] https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mlong-double-64-2

Reply via email to