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;
}
```

Reply via email to