diff --git a/initialized_test.cpp b/initialized_test.cpp
new file mode 100644
index 0000000..9380957
--- /dev/null
+++ b/initialized_test.cpp
@@ -0,0 +1,116 @@
+// Copyright 2010, Niels Dekker.
+//
+// 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)
+//
+// Test program for boost::initialized
+The template initialized
+offers both value-initialization and direct-initialization.
+It is especially useful as a data member type, allowing the very same object
+to be either direct-initialized or value-initialized.
+
The const
object initialized_value
allows value-initializing a variable as follows:
@@ -216,37 +223,65 @@ it may 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 aggregates may in some cases -be partially, or even entirely left uninitialized, when they should be value-initialized. +All compilers we have tested so far support value-initialization for arithmetic types properly. +However, various compilers may leave some types of aggregates uninitialized, when they +should be value-initialized. Value-initialization of objects of a pointer-to-member type may also +go wrong on various compilers.-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: -
-
-Microsoft Feedback ID 100744 - Value-initialization in new-expression
- Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28 - - -GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members - Reported by Jonathan Wakely, 2006-12-07 - - -GCC Bug 33916 - Default constructor fails to initialize array members - Reported by Michael Elizabeth Chastain, 2007-10-26 - - -Borland Report 51854 - Value-initialization: POD struct should be zero-initialized - Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11 - - |
+
New versions of value_initialized
(Boost release version 1.35 or higher)
-offer a workaround to these issues: value_initialized
will now clear
-its internal data, prior to constructing the object that it contains.
+offer a workaround to these issues: value_initialized
may now clear
+its internal data, prior to constructing the object that it contains. It will do
+so for those compilers that need to have such a workaround, based on the
+compiler defect macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
get()
idiom:
value_initialized<int> x ;+
get(x) = 1 ; // OK
value_initialized<int const> cx ;
get(x) = 1 ; // ERROR: Cannot modify a const object
value_initialized<int> const x_c ;
get(x_c) = 1 ; // ERROR: Cannot modify a const object
value_initialized<int const> const cx_c ;
get(cx_c) = 1 ; // ERROR: Cannot modify a const object
template class initialized<T>
namespace boost {+ +The template class
template<class T>
class initialized
{ +
public : +
initialized() : x() {} +
explicit initialized(T const & arg) : x(arg) {} +
operator T const &() const; +
operator T&(); +
T const &data() const; +
T& data(); +
void swap( value_initialized<T>& ); +
+
private : +
unspecified x ; +
} ; +
+
template<class T> +
T const& get ( initialized<T> const& x ); +
+
template<class T> +
T& get ( initialized<T>& x ); +
+
} // namespace boost +
boost::initialized<T>
supports both value-initialization
+and direct-initialization, so its interface is a superset of the interface
+of value_initialized<T>
: Its default-constructor
+value-initializes the wrapped object just like the default-constructor of
+value_initialized<T>
, but boost::initialized<T>
+also offers an extra explicit
+constructor, which direct-initializes the wrapped object by the specified value.
+
+
+initialized<T>
is especially useful when the wrapped
+object must be either value-initialized or direct-initialized, depending on
+runtime conditions. For example, initialized<T>
could
+hold the value of a data member that may be value-initialized by some
+constructors, and direct-initialized by others.
+On the other hand, if it is known beforehand that the
+object must always be value-initialized, value_initialized<T>
+may be preferable. And if the object must always be
+direct-initialized, none of the two wrappers really needs to be used.
+
initialized_value
@@ -399,6 +480,9 @@ Special thanks to Björn Karlsson who carefully edited and completed this dovalue_initialized was reimplemented by Fernando Cacciola and Niels Dekker for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
+
boost::initialized
was very much inspired by feedback from Edward Diener and + Jeffrey Hellrung. +initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
Developed by Fernando Cacciola, @@ -407,9 +491,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
-Revised 03 October 2009
+Revised 30 May 2010
-© Copyright Fernando Cacciola, 2002, 2009.
+© Copyright Fernando Cacciola, 2002 - 2010.
Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt
diff --git a/value_init_workaround_test.cpp b/value_init_workaround_test.cpp new file mode 100644 index 0000000..190c267 --- /dev/null +++ b/value_init_workaround_test.cpp @@ -0,0 +1,144 @@ +// Copyright 2010, Niels Dekker. +// +// 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) +// +// Test program for the boost::value_initializedworkaround. +// +// 17 June 2010 (Created) Niels Dekker + +// Switch the workaround off, before inluding "value_init.hpp". +#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 +#include + +#include // For cout. +#include // For EXIT_SUCCESS and EXIT_FAILURE. + +namespace +{ + struct empty_struct + { + }; + + // A POD aggregate struct derived from an empty struct. + // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295, + // "VC++ does not value-initialize members of derived classes without + // user-declared constructor", reported in 2009 by Sylvester Hesp: + // https://connect.microsoft.com/VisualStudio/feedback/details/484295 + struct derived_struct: empty_struct + { + int data; + }; + + bool is_value_initialized(const derived_struct& arg) + { + return arg.data == 0; + } + + + class virtual_destructor_holder + { + public: + int i; + virtual ~virtual_destructor_holder() + { + } + }; + + bool is_value_initialized(const virtual_destructor_holder& arg) + { + return arg.i == 0; + } + + // Equivalent to the Stats class from GCC Bug 33916, + // "Default constructor fails to initialize array members", reported in 2007 by + // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 + // and fixed for GCC 4.2.4. + class private_int_array_pair + { + friend bool is_value_initialized(const private_int_array_pair& arg); + private: + int first[12]; + int second[12]; + }; + + bool is_value_initialized(const private_int_array_pair& arg) + { + for ( unsigned i = 0; i < 12; ++i) + { + if ( (arg.first[i] != 0) || (arg.second[i] != 0) ) + { + return false; + } + } + return true; + } + + template + bool is_value_initialized(const T(& arg)[2]) + { + return + is_value_initialized(arg[0]) && + is_value_initialized(arg[1]); + } + + template + bool is_value_initialized(const boost::value_initialized & arg) + { + return is_value_initialized(arg.data()); + } + + // Returns zero when the specified object is value-initializated, and one otherwise. + // Prints a message to standard output if the value-initialization has failed. + template + unsigned failed_to_value_initialized(const T& object, const char *const object_name) + { + if ( is_value_initialized(object) ) + { + return 0u; + } + else + { + std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl; + return 1u; + } + } + +// A macro that passed both the name and the value of the specified object to +// the function above here. +#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value) + + // Equivalent to the dirty_stack() function from GCC Bug 33916, + // "Default constructor fails to initialize array members", reported in 2007 by + // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 + void dirty_stack() + { + unsigned char array_on_stack[4096]; + for (unsigned i = 0; i < sizeof(array_on_stack); ++i) + { + array_on_stack[i] = 0x11; + } + } + +} + + +int main() +{ + dirty_stack(); + + // TODO More types may be added later. + const unsigned num_failures = + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized ()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized ()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized ()); + +#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED + // One or more failures are expected. + return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE; +#else + // No failures are expected. + return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +#endif +}