
On Tue, Dec 16, 2008 at 10:19, Giovanni Piero Deretta <gpderetta@gmail.com> wrote:
On Tue, Dec 16, 2008 at 3:03 PM, Pyry Jahkola <pyry.jahkola@gmail.com> wrote:
I'd suggest using a union instead, for the purpose of treating a float as integer:
template <typename To, typename From> inline To bitwise_cast(From const & from) { BOOST_STATIC_ASSERT(sizeof(To) == sizeof(From)); union { To to; From from; } u; u.from = from; return u.to; }
This is also undefined behavior even if it is explicitly supported by most compilers as an extension. It is not necessarily better than a memcpy and might actually be slower.
Empyrically, putting the following into the LLVM online demo (http://llvm.org/demo/) shows that, in llvm-g++ at least, the (intermediate) code generated from the memcpy is optimal: #include <string.h> int foo(float const y) { int x; memcpy(&x,&y,sizeof(int)); return x; } define i32 @_Z3foof(float %y) nounwind readnone { entry: %0 = bitcast float %y to i32 ; <i32> [#uses=1] ret i32 %0 } So since the memcpy is always safe and doesn't break the aliasing rules, it certainly seems the best approach.