Compare commits

..

22 Commits

Author SHA1 Message Date
Jonathan Turkanis
038df9ba32 Branch for Iostreams development
[SVN r42144]
2007-12-18 20:08:11 +00:00
Niels Dekker
01274cf6ac value_init.hpp now no longer distinguished between workaround and non-workaround, because many compilers don't do value-initialization well. Fixed copy construction and assignment -- discussed with Fernando Cacciola
[SVN r41942]
2007-12-09 22:49:58 +00:00
Niels Dekker
8080673977 Added value_init tests if a copy function of T is called when value_initialized<T> is copied -- a case I hadn't thought of before...
[SVN r41919]
2007-12-09 11:53:08 +00:00
Niels Dekker
a470b591fb Added value_init test for an value_initialized<T> object allocated on the heap.
[SVN r41667]
2007-12-03 21:41:59 +00:00
Niels Dekker
e1a63495b6 Added missing #include to value_init_test.cpp. (My mistake!)
[SVN r41648]
2007-12-03 18:20:19 +00:00
Niels Dekker
7300ac83f1 Added value_init test for C style array of bytes
[SVN r41647]
2007-12-03 18:14:37 +00:00
Niels Dekker
882d38c2c7 Added value_init tests, based upon GCC bug report by Jonathan Wakely. Added URL to Borland bug report.
[SVN r41529]
2007-12-01 12:14:37 +00:00
Niels Dekker
33041ad664 Added tests for two more struct types to value_init_test -- discussed with Fernando Cacciola
[SVN r41436]
2007-11-28 17:19:37 +00:00
Niels Dekker
6a2aa822f8 Added value_init test for struct as used in MSVC bug report regarding value-initialization.
[SVN r41423]
2007-11-27 21:34:08 +00:00
Niels Dekker
09ab16bfc1 Checked the result of value_init test function, hoping to pinpoint exactly for what particular type T value_initialized<T> might fail, on some platforms
[SVN r41326]
2007-11-24 11:51:03 +00:00
Niels Dekker
ec46e40809 Code refactoring: removed private base classes of value_initialized, as suggested by Fernando Cacciola.
[SVN r41216]
2007-11-18 22:11:57 +00:00
Beman Dawes
b3a971e7e9 Copyright and/or License cleanup
[SVN r40890]
2007-11-07 16:08:09 +00:00
John Maddock
7ddb559887 Fix path to test case.
[SVN r40736]
2007-11-04 12:01:16 +00:00
Peter Dimov
ea8c99b1d5 Added a sentence with a brief explanation of the intended uses of BOOST_VERIFY.
[SVN r40731]
2007-11-03 22:47:17 +00:00
Peter Dimov
56b0846099 BOOST_VERIFY added.
[SVN r40728]
2007-11-03 20:55:22 +00:00
Niels Dekker
42e0001370 Added value_initialized<T> test, having T as aggregate POD struct. In the past, this would have triggered MSVC warning C4345; this warning is now disabled within value_init.hpp, changeset [40088]
[SVN r40089]
2007-10-16 17:06:39 +00:00
Niels Dekker
cd8f85afee Disabled MSVC warning C4345, in response to Gennadiy Rozental, Boost Developer mailing list, "[utility] value_init warning", October 14, 2007. Push'n'pop reminder from Paul A Bristow taken into account.
[SVN r40088]
2007-10-16 17:00:28 +00:00
Markus Schöpflin
bddd52c4b9 Fixed bug preventing compilation on Tru64/CXX.
[SVN r39918]
2007-10-11 07:36:41 +00:00
Niels Dekker
8f03aeac4e Added unit test to make sure that Visual C++ 7.1 ICE reported by Ralf W. Grosse-Kunstleve (Boost Developers mailing list, subject "utility/value_init.hpp: VC 7.1 ICE & workaround") will not occur anymore.
[SVN r39309]
2007-09-16 09:48:28 +00:00
Niels Dekker
3bb2568fad Visual C++ 7.1 ICE workaround by Ralf W. Grosse-Kunstleve added to ~const_T_base() as well. See also Boost Developers mailing list, subject "utility/value_init.hpp: VC 7.1 ICE & workaround"
[SVN r39308]
2007-09-16 09:33:34 +00:00
Ralf W. Grosse-Kunstleve
01e91a3799 work around Visual C++ 7.1 internal compiler error
[SVN r39302]
2007-09-15 23:11:50 +00:00
Niels Dekker
55f3c351a3 Added MSVC workaround to value_initialized, as described by ticket #1217, proposed at the Boost Developers mailing list, and discussed with Fernando Cacciola.
[SVN r39157]
2007-09-07 17:17:09 +00:00
12 changed files with 103 additions and 321 deletions

View File

@@ -334,7 +334,7 @@ with the exact pointer type used in <code>switcher</code>'s constructor.</p>
<h3><a name="contributors">Contributors</a></h3>
<dl>
<dt><a href="http://www.boost.org/people/ed_brey.htm">Ed Brey</a>
<dt><a href="../../people/ed_brey.htm">Ed Brey</a>
<dd>Suggested some interface changes.
<dt><a href="http://www.moocat.org">R. Samuel Klatchko</a> (<a
@@ -343,7 +343,7 @@ with the exact pointer type used in <code>switcher</code>'s constructor.</p>
<dd>Invented the idiom of how to use a class member for initializing
a base class.
<dt><a href="http://www.boost.org/people/dietmar_kuehl.htm">Dietmar Kuehl</a>
<dt><a href="../../people/dietmar_kuehl.htm">Dietmar Kuehl</a>
<dd>Popularized the base-from-member idiom in his
<a href="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">IOStream
example classes</a>.
@@ -353,7 +353,7 @@ with the exact pointer type used in <code>switcher</code>'s constructor.</p>
can be controlled and automated with macros. The implementation uses
the <a href="../preprocessor/index.html">Preprocessor library</a>.
<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a>
<dt><a href="../../people/daryle_walker.html">Daryle Walker</a>
<dd>Started the library. Contributed the test file <cite><a
href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.
</dl>

View File

@@ -740,16 +740,26 @@ specialisation).</p>
<p>Revised 01 September 2000</p>
<p>
Copyright 2000 Steve Cleary, Beman Dawes, Howard
Hinnant and John Maddock. <br/>
Use, modification and distribution are subject to the
Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt
</a>).
</p>
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided
&quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose.</p>
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
Hinnant and John Maddock.</p>
<p>Maintained by <a href="mailto:john@johnmaddock.co.uk">John
Maddock</a>, the latest version of this file can be found at <a
href="http://www.boost.org/">www.boost.org</a>, and the boost
discussion list at <a
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
<p>.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>

View File

@@ -366,18 +366,17 @@ David Vandevoorde and Nicolai&nbsp;M. Josuttis.
<EM>C++ Templates: The Complete Guide</EM>.
Addison-Wesley, 2002.</DL>
<hr/>
<p>Copyright Jaakko J&auml;rvi, Jeremiah Willcock and Andrew Lumsdaine<BR>
<hr></hr>
<B>Contributed by:</B> <BR>
Jaakko J&auml;rvi, Jeremiah Willcock and Andrew Lumsdaine<BR>
<EM>{jajarvi|jewillco|lums}@osl.iu.edu</EM><BR>
Indiana University<BR>
Open Systems Lab<br/>
Use, modification and distribution are subject to the
Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt
</a>).
</p>
Open Systems Lab
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->

View File

@@ -153,7 +153,7 @@ int main()
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<p><i>Copyright &copy; 2001 <a href=
"http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p>
"../../people/jens_maurer.htm">Jens Maurer</a></i></p>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or

View File

@@ -1,13 +0,0 @@
//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc.
//Distributed under the Boost Software License, Version 1.0. (See accompanying
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
#define UUID_1D94A7C6054E11DB9804B622A1EF5492
#include <boost/exception/info_tuple.hpp>
#include <boost/exception/cloning.hpp>
#include <boost/throw_exception.hpp>
#endif

View File

@@ -10,10 +10,9 @@
#define BOOST_RESULT_OF_HPP
#include <boost/config.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/type_traits/ice.hpp>
#include <boost/type.hpp>
#include <boost/preprocessor.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>

View File

@@ -1,24 +1,37 @@
// (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal.
// (C) Copyright 2002-2007, Fernando Luis Cacciola Carballal.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// 21 Ago 2002 (Created) Fernando Cacciola
// 18 Feb 2008 (Worked around compiler bugs, added initialized_value) Fernando Cacciola, Niels Dekker
// 07 Set 2007 (Worked around MSVC++ bug) Fernando Cacciola, Niels Dekker
// 16 Nov 2007 (Refactoring: removed private base classes) Fernando Cacciola, Niels Dekker
// 09 Dec 2007 (Worked around various compiler bugs) Fernando Cacciola, Niels Dekker
//
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
// Note: The implementation of boost::value_initialized had to deal with the
// fact that various compilers haven't fully implemented value-initialization.
// The constructor of boost::value_initialized<T> works around these compiler
// issues, by clearing the bytes of T, before constructing the T object it
// contains. More details on these issues are at libs/utility/value_init.htm
// fact that various compilers haven't fully implemented value-initialization:
// Microsoft Feedback ID 100744 - Value-initialization in new-expression
// Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
// GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members
// Reported by Jonathan Wakely, 2006-12-07
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
// GCC Bug 33916 - Default constructor fails to initialize array members
// Reported by Michael Elizabeth Chastain, 2007-10-26
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
// Borland Report 51854 - Value-initialization: POD struct should be zero-initialized
// Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-11-09
// http://qc.codegear.com/wc/qcmain.aspx?d=51854
// The constructor of boost::value_initialized<T> works around these issues, by
// clearing the bytes of T, before constructing the T object it contains.
#include <boost/aligned_storage.hpp>
#include <boost/detail/select_type.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <cstring>
@@ -41,13 +54,8 @@ class value_initialized
mutable
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
typename
#endif
aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x;
wrapper * wrapper_address() const
{
return static_cast<wrapper *>( static_cast<void*>(&x));
}
#endif
::boost::aligned_storage<sizeof(wrapper), ::boost::alignment_of<wrapper>::value>::type x;
public :
@@ -59,11 +67,11 @@ class value_initialized
#if _MSC_VER >= 1310
// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345:
// "behavior change: an object of POD type constructed with an initializer of the form ()
// will be default-initialized". It is safe to ignore this warning when using value_initialized.
// will be default-initialized". There is no need to worry about this, though.
#pragma warning(disable: 4345)
#endif
#endif
new (wrapper_address()) wrapper();
new (&x) wrapper();
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
@@ -71,25 +79,28 @@ class value_initialized
value_initialized(value_initialized const & arg)
{
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
void const * const ptr = &(arg.x);
new (&x) wrapper( *static_cast<wrapper const *>(ptr) );
}
value_initialized & operator=(value_initialized const & arg)
{
// Assignment is only allowed when T is non-const.
BOOST_STATIC_ASSERT( ! is_const<T>::value );
*wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address()));
T & this_data = this->data();
T const & arg_data = arg.data();
this_data = arg_data;
return *this;
}
~value_initialized()
{
wrapper_address()->wrapper::~wrapper();
void * const ptr = &x;
static_cast<wrapper *>(ptr)->wrapper::~wrapper();
}
T& data() const
{
return wrapper_address()->data;
void * const ptr = &x;
return static_cast<wrapper *>(ptr)->data;
}
operator T&() const { return this->data(); }
@@ -109,18 +120,6 @@ T& get ( value_initialized<T>& x )
return x.data() ;
}
class initialized_value
{
public :
template <class T> operator T() const
{
return get( value_initialized<T>() );
}
};
} // namespace boost

View File

@@ -21,15 +21,14 @@
<a href="compressed_pair.htm">compressed_pair</a><br>
<a href="current_function.html">current_function</a><br>
<a href="enable_if.html">enable_if</a><br>
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="operators.htm">operators</a><br>
<a href="throw_exception.html">throw_exception</a><br>
<a href="utility.htm">utility</a><br>
<a href="value_init.htm">value_init</a></p>
</blockquote>
<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at

View File

@@ -2029,13 +2029,13 @@ public:
<h2><a name="contributors">Contributors</a></h2>
<dl>
<dt><a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a></dt>
<dt><a href="../../people/dave_abrahams.htm">Dave Abrahams</a></dt>
<dd>Started the library and contributed the arithmetic operators in
<cite><a href=
"../../boost/operators.hpp">boost/operators.hpp</a></cite>.</dd>
<dt><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a></dt>
<dt><a href="../../people/jeremy_siek.htm">Jeremy Siek</a></dt>
<dd>Contributed the <a href="#deref">dereference operators and iterator
helpers</a> in <cite><a href=
@@ -2043,19 +2043,19 @@ public:
contributed <cite><a href=
"iterators_test.cpp">iterators_test.cpp</a></cite>.</dd>
<dt><a href="http://www.boost.org/people/aleksey_gurtovoy.htm">Aleksey
<dt><a href="../../people/aleksey_gurtovoy.htm">Aleksey
Gurtovoy</a></dt>
<dd>Contributed the code to support <a href="#chaining">base class
chaining</a> while remaining backward-compatible with old versions of
the library.</dd>
<dt><a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a></dt>
<dt><a href="../../people/beman_dawes.html">Beman Dawes</a></dt>
<dd>Contributed <cite><a href=
"operators_test.cpp">operators_test.cpp</a></cite>.</dd>
<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a></dt>
<dt><a href="../../people/daryle_walker.html">Daryle Walker</a></dt>
<dd>Contributed classes for the shift operators, equivalence, partial
ordering, and arithmetic conversions. Added the grouped operator

View File

@@ -68,7 +68,7 @@ const std::list&lt;T&gt;::iterator next = boost::next(prev, 2);</pre>
<p>The distance from the given iterator should be supplied as an absolute value. For
example, the iterator four iterators prior to the given iterator <code>p</code>
may be obtained by <code>prior(p, 4)</code>.</p>
<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>. Two-argument versions by Daniel Walker.</p>
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>. Two-argument versions by Daniel Walker.</p>
<h2><a name="Class_noncopyable">Class noncopyable</a></h2>
<p>Class <strong>noncopyable</strong> is a base class.&nbsp; Derive your own class
from <strong>noncopyable</strong> when you want to prohibit copy construction
@@ -89,7 +89,7 @@ const std::list&lt;T&gt;::iterator next = boost::next(prev, 2);</pre>
to verify class <b>noncopyable</b> works as expected. It has have been run
successfully under GCC 2.95, Metrowerks CodeWarrior 5.0, and Microsoft Visual
C++ 6.0 sp 3.</p>
<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.</p>
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
<h3>Example</h3>
<blockquote>
<pre>// inside one of your own headers ...

View File

@@ -17,13 +17,11 @@
<dl>
<dt><a href="#rationale">Rationale</a></dt>
<dt><a href="#intro">Introduction</a></dt>
<dt><a href="#details">Details</a></dt>
</dl>
<ul>
<li><a href="#valueinit">value-initialization</a></li>
<li><a href="#valueinitsyn">value-initialization syntax</a></li>
<li><a href="#compiler_issues">compiler issues</a></li>
</ul>
@@ -32,8 +30,7 @@
</dl>
<ul>
<li><a href="#val_init"><code>template class value_initialized&lt;T&gt;</code></a></li>
<li><a href="#initialized_value"><code>class initialized_value</code></a></li>
<li><a href="#val_init"><code>value_initialized&lt;&gt;</code></a></li>
</ul>
<a href="#acknowledgements">Acknowledgements</a><br>
@@ -47,104 +44,24 @@
for initialization. Depending on the type, the value of a newly constructed
object can be zero-initialized (logically 0), default-constructed (using
the default constructor), or indeterminate. When writing generic code,
this problem must be addressed. The template <code>value_initialized</code> provides
this problem must be addressed. <code>value_initialized</code> provides
a solution with consistent syntax for value initialization of scalar,
union and class types.
Moreover, <code>value_initialized</code> offers a workaround to various
compiler issues regarding value-initialization.
Furthermore a convenience class, <code>initialized_value</code> is provided,
to avoid repeating the type name when retrieving the value from a
<code>value_initialized&lt;T&gt;</code> object.
<br>
union and class types. <br>
</p>
<h2><a name="intro"></a>Introduction</h2>
<p>
There are various ways to initialize a variable, in C++. The following
declarations all <em>may</em> have a local variable initialized to its default
value:
<pre>
T1 var1;
T2 var2 = 0;
T3 var3 = {};
T4 var4 = T4();
</pre>
Unfortunately, whether or not any of those declarations correctly
initialize the variable very much depends on its type. The first
declaration is valid for any <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
DefaultConstructible</a> type (by definition).
However, it does not always do an initialization!
It correctly initializes the variable when it's an instance of a
class, and the author of the class has provided a proper default
constructor. On the other hand, the value of <code>var1</code> is <em>indeterminate</em> when
its type is an arithmetic type, like <code>int</code>, <code>float</code>, or <code>char</code>.
An arithmetic variable
is of course initialized properly by the second declaration, <code>T2
var2 = 0</code>. But this initialization form usually won't work for a
class type (unless the class was especially written to support being
initialized that way). The third form, <code>T3 var3 = {}</code>
initializes an aggregate, typically a "C-style" <code>struct</code> or a "C-style" array.
However, the syntax is not allowed for a class that has an explicitly declared
constructor. (But watch out for an upcoming C++ language change,
by Bjarne Stroustrup et al [<a href="#references">1</a>]!)
The fourth form is the most generic form of them, as it
can be used to initialize arithmetic types, class types, aggregates, pointers, and
other types. The declaration, <code>T4 var4 = T4()</code>, should be read
as follows: First a temporary object is created, by <code>T4()</code>.
This object is <a href="#valueinit">value-initialized</a>. Next the temporary
object is copied to the named variable, <code>var4</code>. Afterwards, the temporary
is destroyed. While the copying and the destruction are likely to
be optimized away, C++ still requires the type <code>T4</code> to be
<a href="CopyConstructible.html">CopyConstructible</a>.
(So <code>T4</code> needs to be <em>both</em> DefaultConstructible <em>and</em> CopyConstructible.)
A class may not be CopyConstructible, for example because it may have a
private and undefined copy constructor,
or because it may be derived from <a href="utility.htm#Class_noncopyable">boost::noncopyable</a>.
Scott Meyers [<a href="#references">2</a>] explains why a class would be defined like that.
</p>
<p>
There is another, less obvious disadvantage to the fourth form, <code>T4 var4 = T4()</code>:
It suffers from various <a href="#compiler_issues">compiler issues</a>, causing
a variable to be left uninitialized in some compiler specific cases.
</p>
<p>
The template <a href="#val_init"><code>value_initialized</code></a>
offers a generic way to initialize
an object, like <code>T4 var4 = T4()</code>, but without requiring its type
to be CopyConstructible. And it offers a workaround to those compiler issues
regarding value-initialization as well! It allows getting an initialized
variable of any type; it <em>only</em> requires the type to be DefaultConstructible.
A properly <em>value-initialized</em> object of type <code>T</code> is
constructed by the following declaration:
<pre>
value_initialized&lt;T&gt; var;
</pre>
</p>
<p>
The convenience class <a href="#initialized_value"><code>initialized_value</code></a>
allows value-initializing a variable as follows:
<pre>
T var = initialized_value();
</pre>
This form of initialization is also very similar to <code>T4 var4 = T4()</code>,
but robust against the aforementioned compiler issues.
</p>
<h2><a name="details"></a>Details</h2>
<p>The C++ standard [<a href="#references">3</a>] contains the definitions
<p>The C++ standard [<a href="#references">1</a>] contains the definitions
of <code>zero-initialization</code> and <code>default-initialization</code>.
Informally, zero-initialization means that the object is given the initial
value 0 (converted to the type) and default-initialization means that
POD [<a href="#references">4</a>] types are zero-initialized, while non-POD class
POD [<a href="#references">2</a>] types are zero-initialized, while class
types are initialized with their corresponding default constructors. A
<i>declaration</i> can contain an <i>initializer</i>, which specifies the
object's initial value. The initializer can be just '()', which states that
the object shall be value-initialized (but see below). However, if a <i>declaration</i>
the object shall be default-initialized (but see below). However, if a <i>declaration</i>
has no <i>initializer</i> and it is of a non-<code>const</code>, non-<code>static</code>
POD type, the initial value is indeterminate: <cite>(see &sect;8.5, [dcl.init], for the
POD type, the initial value is indeterminate:<cite>(see &sect;8.5 for the
accurate definitions).</cite></p>
<pre>int x ; // no initializer. x value is indeterminate.<br>std::string s ; // no initializer, s is default-constructed.<br><br>int y = int() ; <br>// y is initialized using copy-initialization<br>// but the temporary uses an empty set of parentheses as the initializer,<br>// so it is default-constructed.<br>// A default constructed POD type is zero-initialized,<br>// therefore, y == 0.<br><br>void foo ( std::string ) ;<br>foo ( std::string() ) ; <br>// the temporary string is default constructed <br>// as indicated by the initializer () </pre>
@@ -170,11 +87,14 @@ the object shall be value-initialized (but see below). However, if a <i>declara
<p>In order to specify value-initialization of an object we need to use the
empty-set initializer: (). </p>
<p><i>(but recall that the current C++ Standard states that '()' invokes default-initialization,
not value-initialization)</i></p>
<p>As before, a declaration with no intializer specifies default-initialization,
and a declaration with a non-empty initializer specifies copy (=xxx) or
direct (xxx) initialization. </p>
<pre>template&lt;class T&gt; void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialized</pre>
<pre>template&lt;class T&gt; void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialied</pre>
<h4><a name="valueinitsyn">value-initialization</a> syntax</h4>
@@ -182,7 +102,7 @@ the object shall be value-initialized (but see below). However, if a <i>declara
parentheses is not permitted by the syntax of initializers because it is
parsed as the declaration of a function taking no arguments: </p>
<pre>int x() ; // declares function int(*)()</pre>
<pre>int x() ; // declares function int(*)()<br>int y ( int() ) ; // decalares function int(*)( int(*)() )</pre>
<p>Thus, the empty () must be put in some other initialization context.</p>
@@ -204,50 +124,8 @@ data member:</p>
<pre>template&lt;class T&gt; <br>struct W <br>{<br> // value-initialization of 'data' here.<br> W() : data() {}<br> T data ;<br>} ;<br>W&lt;int&gt; w ;<br>// w.data is value-initialized for any type. </pre>
<p>This is the solution as it was supplied by earlier versions of the
<code>value_initialized&lt;T&gt;</code> template
class. Unfortunately this approach suffered from various compiler issues.</p>
<h4><a name="compiler_issues">compiler issues</a> </h4>
Various compilers haven't yet fully implemented value-initialization.
So when an object should be <em>value-initialized</em> (according to the C++ Standard),
it <em>may</em> in practice still be left uninitialized, because of those
compiler issues! It's hard to make a general statement on what those issues
are like, because they depend on the compiler you are using, its version number,
and the type of object you would like to have value-initialized.
Compilers usually support value-initialization for built-in types properly.
But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em>
be partially, or even entirely left uninitialized, when they should be value-initialized.
</p>
<p>
We have encountered issues regarding value-initialization on compilers by
Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues:
<table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" >
<tr><td>
<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744">
Microsoft Feedback ID 100744 - Value-initialization in new-expression</a>
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
<br>
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">
GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a>
<br>Reported by Jonathan Wakely, 2006-12-07
<br>
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916">
GCC Bug 33916 - Default constructor fails to initialize array members</a>
<br>Reported by Michael Elizabeth Chastain, 2007-10-26
<br>
<a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854">
Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a>
<br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11
<br>
</td></tr></table>
</p><p>
New versions of <code>value_initialized</code>
(Boost release version 1.35 or higher)
offer a workaround to these issues: <code>value_initialized</code> will now clear
its internal data, prior to constructing the object that it contains.
</p>
<p><code>This is the solution supplied by the value_initialized&lt;&gt; template
class.</code></p>
<h2><a name="types"></a>Types</h2>
@@ -311,72 +189,25 @@ wrapped object from within a constant wrapper can be avoided if access to
the wrapped object is always performed with the <code>get()</code> idiom:</p>
<pre>value_initialized&lt;int&gt; x ;<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int&gt; const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int const&gt; const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
<h2><a name="initialized_value"><code>class initialized_value</code></a></h2>
<pre>
namespace boost {
class initialized_value
{
public :
template &lt;class T&gt; operator T() const ;
};
} // namespace boost
</pre>
The class <code>initialized_value</code> provides a convenient way to get
an initialized value: its conversion operator provides an appropriate
<em>value-initialized</em> object for any CopyConstructible type.
Suppose you need to have an initialized variable of type <code>T</code>.
You could do it as follows:
<pre>
T var = T();
</pre>
But as mentioned before, this form suffers from various compiler issues.
The template <code>value_initialized</code> offers a workaround:
<pre>
T var = get( value_initialized&lt;T&gt;() );
</pre>
Unfortunately both forms repeat the type name, which
is rather short now (<code>T</code>), but could of course be
more like <code>Namespace::Template&lt;Arg&gt;::Type</code>.
Instead, one could use <code>initialized_value</code> as follows:
<pre>
T var = initialized_value();
</pre>
<h3><a name="references">References</a></h3>
[1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
in the next version of C++.
This would allow a variable <code>var</code> of any DefaultConstructible type
<code>T</code> to be <em>value-initialized</em> by doing <code>T var = {}</code>.
The papers are listed at Bjarne's web page,
<a href="http://www.research.att.com/~bs/WG21.html">My C++ Standards committee papers</a> <br>
[2] Scott Meyers, Effective C++, Third Edition, item 6,
<em>Explicitly disallow the use of compiler-generated functions you do not want</em>,
<a href="http://www.aristeia.com/books.html">Scott Meyers: Books and CDs</a> <br>
[3] The C++ Standard, Second edition (2003), ISO/IEC 14882:2003 <br>
[4] POD stands for "Plain Old Data"
[1] The C++ Standard, ISO/IEC 14882:98 <br>
[2] Plain Old Data
<h3><a name="acknowledgements"></a>Acknowledgements</h3>
value_initialized was developed by Fernando Cacciola, with help and
suggestions from David Abrahams and Darin Adler.<br>
Special thanks to Bj&ouml;rn Karlsson who carefully edited and completed this documentation.
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
</p>
Special thanks to Bj<EFBFBD>rn Karlsson who carefully edited and completed this documentation.
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
the latest version of this file can be found at <a
href="http://www.boost.org">www.boost.org</a>.
href="http://www.boost.org">www.boost.org</a>, and the boost discussion list
at <a href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.
</p>
<hr>
<p>Revised 16 January 2008</p>
<p>Revised 19 September 2002</p>
<p>&copy; Copyright Fernando Cacciola, 2002, 2008.</p>
<p>&copy; Copyright Fernando Cacciola, 2002.</p>
<p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>

View File

@@ -1,4 +1,4 @@
// Copyright 2002-2008, Fernando Luis Cacciola Carballal.
// Copyright 2002, Fernando Luis Cacciola Carballal.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -6,8 +6,7 @@
//
// Test program for "boost/utility/value_init.hpp"
//
// 21 Ago 2002 (Created) Fernando Cacciola
// 18 Feb 2008 (Added tests regarding compiler issues and initialized_value) Fernando Cacciola, Niels Dekker
// Initial: 21 Agu 2002
#include <cstring> // For memcmp.
#include <iostream>
@@ -52,7 +51,7 @@ struct NonPODBase
struct NonPOD : NonPODBase
{
NonPOD () : id() {}
explicit NonPOD ( std::string const& id_) : id(id_) {}
NonPOD ( std::string const& id_) : id(id_) {}
friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
{ return os << '(' << npod.id << ')' ; }
@@ -180,32 +179,6 @@ struct CopyFunctionCallTester
};
template<class T>
void check_initialized_value ( T const& y )
{
T initializedValue = boost::initialized_value() ;
BOOST_CHECK ( y == initializedValue ) ;
}
#ifdef __BORLANDC__
#if __BORLANDC__ == 0x582
void check_initialized_value( NonPOD const& )
{
// The initialized_value check is skipped for Borland 5.82
// and this type (NonPOD), because the following statement
// won't compile on this particular compiler version:
// NonPOD initializedValue = boost::initialized_value() ;
//
// This is caused by a compiler bug, that is fixed with a newer version
// of the Borland compiler. The Release Notes for Delphi(R) 2007 for
// Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
// say about similar statements:
// both of these statements now compile but under 5.82 got the error:
// Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)'
}
#endif
#endif
//
// This test function tests boost::value_initialized<T> for a specific type T.
// The first argument (y) is assumed have the value of a value-initialized object.
@@ -215,13 +188,9 @@ template<class T>
bool test ( T const& y, T const& z )
{
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
check_initialized_value(y);
boost::value_initialized<T> x ;
BOOST_CHECK ( y == x ) ;
BOOST_CHECK ( y == boost::get(x) ) ;
static_cast<T&>(x) = z ;
boost::get(x) = z ;
BOOST_CHECK ( x == z ) ;
@@ -233,13 +202,6 @@ bool test ( T const& y, T const& z )
x_c_ref = z ;
BOOST_CHECK ( x_c == z ) ;
boost::value_initialized<T> const copy1 = x;
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
boost::value_initialized<T> copy2;
copy2 = x;
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
BOOST_CHECK ( y == *ptr ) ;
@@ -305,10 +267,6 @@ int test_main(int, char **)
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);