Boost logo

Boost-Commit :

From: asutton_at_[hidden]
Date: 2008-07-18 12:43:02


Author: asutton
Date: 2008-07-18 12:43:02 EDT (Fri, 18 Jul 2008)
New Revision: 47573
URL: http://svn.boost.org/trac/boost/changeset/47573

Log:
Fixed a type punning warning by hiding the cast behind a union (union_cast<>).

Text files modified:
   sandbox/SOC/2008/graphs/trunk/boost/blob.hpp | 34 ++++++++++++++++++++++++++++++----
   1 files changed, 30 insertions(+), 4 deletions(-)

Modified: sandbox/SOC/2008/graphs/trunk/boost/blob.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/boost/blob.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/boost/blob.hpp 2008-07-18 12:43:02 EDT (Fri, 18 Jul 2008)
@@ -6,14 +6,32 @@
 
 #include <boost/functional/hash.hpp>
 
+namespace detail
+{
+ // Not for the faint of heart. This helps get around type punning issues
+ // by using a union to hide the explicit recast of an array of bytes to
+ // a real object.
+ template <typename T>
+ union union_caster
+ {
+ inline union_caster(void* src) : src(src) { }
+ T cast;
+ void* src;
+ };
+
+ // Use the union caster to affect type punning.
+ template <typename T>
+ inline T union_cast(void* x)
+ { union_caster<T> u(x); return u.cast; }
+}
+
 /**
  * The blob type is used to allocate a small buffer of memory that can be
  * reinterpreted as a type of the same size. This is used solely as a means
  * of deferring the immediate need for the type of an object if you can guess
  * its size.
  *
- * One can imagine this stands for "Binary Little OBject". Little because you
- * probably don't want to copy these around all over the place.
+ * One can imagine this stands for "Binary Little OBject".
  *
  * If you're going to write something hacky, you may as well try to make it a
  * little bit pretty.
@@ -45,10 +63,18 @@
 
     /** Get the value of the blob object, returning it as an object of type T. */
     template <typename T>
- inline T& get() const
+ inline T& get()
+ {
+ static_assert(sizeof(T) == N, "Getting value of wrong size");
+ return *detail::union_cast<T*>(mem);
+ }
+
+ /** Get the value of the blob object, returning it as an object of type T. */
+ template <typename T>
+ inline T const& get() const
     {
         static_assert(sizeof(T) == N, "Getting value of wrong size");
- return *reinterpret_cast<T*>(mem);
+ return *detail::union_cast<T const*>(mem);
     }
 
     /** @name Equality Comparable


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk