* 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
