bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] variants: avoid type punning issue.


From: Theophile Ranquet
Subject: [PATCH] variants: avoid type punning issue.
Date: Tue, 29 Jan 2013 22:59:03 +0100

This is based on what Scott Meyers recommends in 'Effective C++'.

Use a static_cast on void* rather than directly use a reinterpret_cast, which
can have nefarious effects on objects.  However, even though following this
guideline is good practice in general, I am not quite sure how relevant it is
when applied to conversions from POD to objects.  Actually, it might very well
be the opposite: isn't this exactly what reinterpret_cast is for? What we
really want *is* to transmit the memory map as a series of bytes, which, if I
am correct, falls into the kind of "low level" hack for which this cast is
meant.

In any case, this silences the warning, which will be greatly appreciated by
anyone using variants with a compiler supporting -fstrict-aliasing.

* data/variant.hh (as): Here.
* tests/c++.at (Exception safety): Revert commit ddb9db15, type punning
is no longer an issue.
---
 data/variant.hh | 10 ++++++++--
 tests/c++.at    |  2 +-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/data/variant.hh b/data/variant.hh
index 047e641..e2a537a 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -142,7 +142,10 @@ m4_define([b4_variant_define],
     {]b4_parse_assert_if([
       YYASSERT (tname == typeid (T).name ());
       YYASSERT (sizeof (T) <= S);])[
-      return reinterpret_cast<T&> (buffer.raw);
+      {
+        void *dummy = buffer.raw;
+        return *static_cast<T*> (dummy);
+      }
     }
 
     /// Const accessor to a built \a T (for %printer).
@@ -152,7 +155,10 @@ m4_define([b4_variant_define],
     {]b4_parse_assert_if([
       YYASSERT (tname == typeid (T).name ());
       YYASSERT (sizeof (T) <= S);])[
-      return reinterpret_cast<const T&> (buffer.raw);
+      {
+        const void *dummy = buffer.raw;
+        return *static_cast<const T*> (dummy);
+      }
     }
 
     /// Swap the content with \a other, of same type.
diff --git a/tests/c++.at b/tests/c++.at
index a21fb4e..874d640 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -804,7 +804,7 @@ main (int argc, const char *argv[])
 }
 ]])
 AT_BISON_CHECK([[-o input.cc --report=all input.yy]])
-AT_COMPILE_CXX([input], [[$NO_STRICT_ALIAS_CXXFLAGS input.cc]])
+AT_COMPILE_CXX([[input]])
 
 AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
 [[exception caught: reduction
-- 
1.8.1.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]