News for hackers. Stuff that matters.
Re:With Undefined Behavior, Anything Is Possible by raphlinus on Friday August 17, 2018 @09:21PM (#17786407)
That puts you pretty firmly in what I call the "semi-portable" category (I would say "unportable" but wasm is very likely going to have flavors, such as a 64 bit pointer variant).

But if you're being careful, you can do type-punning. The "modern" way is generally with memcpy, but union can be valid if done carefully. The clearest statement I was able to find of this is [1]. I find it frustrating that it's so hard to get a clear read on this. For example, if as Regehr says union-based punning is reliable, then what was the concern that the linked Linux kernel patch trying to address? I haven't dug into it in super detail.

[1] https://blog.regehr.org/archives/1307#comment-18418

Re:With Undefined Behavior, Anything Is Possible by saagarjha on Friday August 17, 2018 @11:34PM (#17786712)
IMO it’s pretty iffy and you should steer clear of it, since the rules around it seem to be murky. I think the actual rule is that it’s illegal in C++, and valid in C99 and C11 but only because it was included in a footer note as an afterthought in the standard.
Re:With Undefined Behavior, Anything Is Possible by comex on Saturday August 18, 2018 @12:25AM (#17786861)
From a standards perspective that’s pretty much right AFAIK. From a practical perspective, it’s also explicitly endorsed in the GCC manual, so I don’t think there’s much risk of popular compilers breaking it in the foreseeable future:

> The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. So, the code above works as expected.

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

Re:With Undefined Behavior, Anything Is Possible by jancsika on Saturday August 18, 2018 @06:18PM (#17791130)
So what is the well-defined and performant way to fetch the exponent and mantissa of a double in standard C?
Re:With Undefined Behavior, Anything Is Possible by saagarjha on Saturday August 18, 2018 @07:55PM (#17791603)
Use frexp from <math.h>.
Re:With Undefined Behavior, Anything Is Possible by jancsika on Sunday August 19, 2018 @10:52AM (#17794505)
The implementation for frexp uses type-punning.

Also, it adds a denormal and inf check which I don't need in this particular hot loop.

Re:With Undefined Behavior, Anything Is Possible by saagarjha on Sunday August 19, 2018 @06:39PM (#17796582)
Does it? On my computer it's a builtin (__builtin_frexp). But even if it did use type-punning, that doesn't make it legal for your program to do it. I don't believe there's any requirements on the C standard library to follow the standard themselves.

To answer the second part of your response, the correct way to do this yourself would be to memcpy the double and then inspect the result directly. Any compiler worth its salt will end up generating the assembly code you want (namely, no call to memcpy, just a couple of arithmetic shifts and masks).

Re:With Undefined Behavior, Anything Is Possible by jancsika on Monday August 20, 2018 @02:27PM (#17802471)
> To answer the second part of your response, the correct way to do this yourself would be to memcpy the double and then inspect the result directly. Any compiler worth its salt will end up generating the assembly code you want (namely, no call to memcpy, just a couple of arithmetic shifts and masks).

What does a compiler "worth its salt" do with the memcpy at "-O0"?

Re:With Undefined Behavior, Anything Is Possible by saagarjha on Monday August 20, 2018 @03:00PM (#17802808)
Re:With Undefined Behavior, Anything Is Possible by jancsika on Saturday August 18, 2018 @06:05PM (#17791059)
To be clear, the use case I have in mind has a soft realtime performance requirements.

So I only see two options:

1. Use memcpy, blindly hope that gcc optimizes it to the same bitmath I'm currently using, and blindly hope that gcc supports that optimized path for the foreseeable future.

2. Use the union type-punning trick, and blindly hope gcc supports their extension for the foreseeable future.

#1 above requires me to blindly hope twice, whereas #2 requires only one instance of blind hope. Furthermore, I already know how the blind hope of gcc optimizing memcpy into bitmath turns out-- gcc does not optimize it in this way.

So I cannot see any alternative to relying on the union type-punning trick in this case.

Edit: clarification

Re:With Undefined Behavior, Anything Is Possible by userbinator on Friday August 17, 2018 @11:47PM (#17786748)
That article seems to imply that the only way out of this mess is to turn off strict aliasing, since easy type punning and other related low-level processing is literally one of the main reasons to use C. I agree completely.