* Jakub Jelinek:

> On Tue, Mar 10, 2026 at 08:14:11AM +0100, Florian Weimer wrote:
>> > The g++.dg/reflect/anon4.C test FAILs on i686-linux, because with
>> > excess precision the store to .c rounds to double precision, but comparison
>> > of it against 3.14 constant doesn't.
>> >
>> > Tested on x86_64-linux and i686-linux, committed to trunk as obvious.
>> >
>> > 2026-03-02  Jakub Jelinek  <[email protected]>
>> >
>> >    * g++.dg/reflect/anon4.C (test): Use (double) 3.14 instead of 3.14 in
>> >    comparisons.
>> >
>> > --- gcc/testsuite/g++.dg/reflect/anon4.C.jj        2026-03-02 
>> > 07:43:12.513785271 +0100
>> > +++ gcc/testsuite/g++.dg/reflect/anon4.C   2026-03-02 07:56:49.168129712 
>> > +0100
>> > @@ -28,6 +28,6 @@ void test ()
>> >  
>> >    constexpr foo bar1 { .i = 42, .c = 3.14 };
>> >  
>> > -  static_assert (bar1.c == 3.14);
>> > -  static_assert (bar1.[: ^^foo::c :] == 3.14);
>> > +  static_assert (bar1.c == (double) 3.14);
>> > +  static_assert (bar1.[: ^^foo::c :] == (double) 3.14);
>> >  }
>> 
>> I'm curious why this happens.  Shouldn't 3.14 have type double in the
>> first place?  Does GCC represent double values using long double
>> internally?
>
> When using FLT_EVAL_METHOD 2 yes.  All constants are evaluated to the
> long double precision in that case, and only explicit casts and assignments
> to double/float/_Float64/_Float32/_Float16 etc. vars actually round that
> to a format with less precision.  3.14 still has double type, but precision
> of long double.
> FLT_EVAL_METHOD 2 is on by default in -std=c* modes for ia32 (unless
> -mfpmath=sse -msse2 is used).  -fexcess-precision= can change that default.
> So, e.g.
> const float a = 3.14L - 3.14f;
> will be for FLT_EVAL_METHOD == 2 0.0f rather than -0x1.c28f5cp-24f .

So decltype(x) can be float, but the stored value is actually
represented as a long double?  That's really weird.

Suddenly pointer provenience (including provenience on integers) does
not look so strange anymore …

Thanks,
Florian

Reply via email to