On Sun, Apr 19, 2026 at 08:55:35AM -0400, Jeffrey Walton wrote:
> On Sun, Apr 19, 2026 at 7:53 AM Mohammad-Reza Nabipoor
> <[email protected]> wrote:
> >
> > The following program produces wrong result on CentOS 7.9 (cfarm112),
> > and on Alpine Linux (cfarm27 and cfarm437):
> >
> > ```c
> > #include "c-strtod.h"
> >
> > #include <stdio.h>
> > #include <stdint.h>
> >
> > int
> > main()
> > {
> > union
> > {
> > float f;
> > uint32_t i;
> > } u;
> >
> > u.f = c_strtof ("-nan", NULL);
> > printf ("f:%f x:0x%08x\n", u.f, u.i);
> > return 0;
> > }
> > ```
> >
> > Output:
> >
> > f:nan x:0x7fc00000
> >
> > Expected output:
> >
> > f:-nan x:0xffc00000
> >
> >
> > You can find a sample package on the mentioned machines on Compile Farm:
> > ~mnabipoor/x-0.1.tar.gz
>
> The sample program smells of undefined behavior. I don't think you
> can access both u.f and u.i members of the union. You have to pick
> one or the other, and the one selected is the one that was written to,
> which is u.f due to `u.f = c_strtof ("-nan", NULL);`.
>
> The finding may be valid, but the sample program looks off.
>
No. The program is valid in C. It's UB in C++.
You can change the the program to the following and get the same result:
```c
int
main()
{
float f;
uint32_t i;
char *end;
f = c_strtof ("-nan", &end);
_Static_assert(sizeof(f) == sizeof(i), "");
memcpy(&i, &f, sizeof(i));
printf ("f:%f x:0x%08x\n", f, i);
return 0;
}
```