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