Comment by burnt-resistor
1 day ago
No, just no. And, never use sscanf().
This is totally pointless when serialization to and from an unsigned integer that's binary equivalent would be perfectly reversible and therefore wouldn't lose any information.
double f = 0.0/0.0; // might need some compiler flags to make this a soft error.
double g;
char s[9];
assert(sizeof double == sizeof uint64_t);
snprintf(s, 9, "%0" PRIu64, *(uint64_t *)(&f));
snscanf(s, 9, "%0" SCNu64, (uint64_t *)(&g));
If you want something shorter, apply some sort of heuristic that doesn't sacrifice faithful reproduction of the original representation, e.g., idempotency.
Off-topic, For this kind of pointer casting, shouldn't you be using a union? I believe this is undefined behaviour, as written.
As written, it is UB, yes, but certainly in C++, and, I think, also in C, using a union is undefined behavior, too. I think (assuming isn’t and float to be of the same size) the main risk is that, if you do
that the compiler can think the assignment to foo.f isn’t used anywhere, and thus can chose not to do it.
In C++, you have to use memmove (compilers can and often do recognize that idiom)
Yes, it violates the standard, although in practice it should work because the alignment is the same.
If the goal is just to reliably serialize and deserialize floating point numbers, use `%a` instead. It will print and read hexadecimal floating point literals.