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 .

        Jakub

Reply via email to