[Boost-bugs] [Boost C++ Libraries] #1217: value_initialized leaves data uninitialized, when using MSVC

Subject: [Boost-bugs] [Boost C++ Libraries] #1217: value_initialized leaves data uninitialized, when using MSVC
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2007-08-27 21:39:41


#1217: value_initialized leaves data uninitialized, when using MSVC
--------------------------+-------------------------------------------------
 Reporter: Niels Dekker | Type: Bugs
   Status: new | Milestone: To Be Determined
Component: None | Version: Boost 1.34.1
 Severity: Problem | Keywords:
--------------------------+-------------------------------------------------
 The data of an instance of boost::value_initialized<T> may not be
 initialized properly, when using Microsoft Visual C++. I already contacted
 Fernando Cacciola, the author of value_initialized, and we have developed
 a workaround, that I would like to propose.

 == The problem ==
 There are two kinds of types, for which the issue is relevant, for
 different reasons:

 When T is an aggregate class or struct that contains both POD and non-POD
 members, the constructor of value_initialized<T> will typically leave the
 POD members of T uninitialized, when using MSVC:
 {{{
   #include <boost/utility/value_init.hpp>

   struct A {
     std::string s;
     int i;
   };

   boost::value_initialized<A> a;
   BOOST_CHECK( get(a).i == 0 ); // Will fail on MSVC!
 }}}

 This is caused by a compiler bug, reported by Pavel at the Microsoft
 Connect website, 7/28/2005, Feedback ID 100744,
 [https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
 Value-initialization in new-expression] The report was closed at
 11/14/2006, and its status was set to "Closed (Won't Fix)". The bug
 appears relevant to all versions of MSVC, including the next one (MSVC
 2008, code name "Orcas").

 When T is an array of a POD type, MSVC 2005 provides an interesting
 warning, within the constructor of the base class of value_initialized<T>:
 {{{
 warning C4351: new behavior: elements of array 'T' will be default
 initialized.
 }}}
 This tells us that an older version of the compiler wouldn't properly
 initialize value_initialized<T>. And indeed the following check fails,
 when using the 2003 version of MSVC:
 {{{
   typedef int B[2];
   boost::value_initialized<B> b; // MSVC 2005 warning C4351: new
 behavior!
   BOOST_CHECK( get(b)[1] == 0 ); // Fails on MSVC 2003 (BOOST_MSVC ==
 1310).
 }}}

 == The proposed workaround ==
 A new version of value_init.hpp is attached to this report, which includes
 a workaround for MSVC. Basically, when constructing value_initialized<T>
 it clears the bytes of T, just before constructing T itself. It does so
 by having the bytes of T stored in an instance of aligned_storage::type,
 and memsetting those bytes to zero before doing a placement new for type
 T, at the location of the bytes.

 The workaround works well for MSVC, because for a built-in type, the value
 zero always has a bit pattern of only zero's, on any platform supported by
 this compiler, AFAIK.

 Note that the workaround itself is a correct and standard compliant
 implementation of boost::value_initialized, but it may have a small
 performance penalty in comparison to the original version.

 --
 Niels Dekker
 [[BR]]http://www.xs4all.nl/~nd/dekkerware
 [[BR]]Scientific programmer at LKEB, Leiden University Medical Center

--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/1217>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.


This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:56 UTC