Ticket #3869: value_init_workaround_test.cpp

File value_init_workaround_test.cpp, 3.3 KB (added by niels_dekker, 12 years ago)
Line 
1// Copyright 2010, Niels Dekker.
2//
3// Distributed under the Boost Software License, Version 1.0. (See
4// accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6//
7// Test program for the boost::value_initialized<T> workaround.
8//
9// 30 May 2010 (Created) Niels Dekker
10
11// Switch the workaround off, before inluding "value_init.hpp".
12#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
13#include <boost/utility/value_init.hpp>
14
15#include <iostream> // For cout.
16#include <cstdlib> // For EXIT_SUCCESS and EXIT_FAILURE.
17
18namespace
19{
20 struct empty_struct
21 {
22 };
23
24 // A POD aggregate struct derived from an empty struct.
25 // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
26 // "VC++ does not value-initialize members of derived classes without
27 // user-declared constructor", reported in 2009 by Sylvester Hesp:
28 // https://connect.microsoft.com/VisualStudio/feedback/details/484295
29 struct derived_struct: empty_struct
30 {
31 int data;
32 };
33
34 bool is_value_initialized(const derived_struct& arg)
35 {
36 return arg.data == 0;
37 }
38
39
40 class virtual_destructor_holder
41 {
42 public:
43 int i;
44 virtual ~virtual_destructor_holder()
45 {
46 }
47 };
48
49 bool is_value_initialized(const virtual_destructor_holder& arg)
50 {
51 return arg.i == 0;
52 }
53
54 template <typename T>
55 bool is_value_initialized(const T(& arg)[2])
56 {
57 return
58 is_value_initialized(arg[0]) &&
59 is_value_initialized(arg[1]);
60 }
61
62 template <typename T>
63 bool is_value_initialized(const boost::value_initialized<T>& arg)
64 {
65 return is_value_initialized(arg.data());
66 }
67
68 // Returns zero when the specified object is value-initializated, and one otherwise.
69 // Prints a message to standard output if the value-initialization has failed.
70 template <class T>
71 unsigned failed_to_value_initialized(const T& object, const char *const object_name)
72 {
73 if ( is_value_initialized(object) )
74 {
75 return 0u;
76 }
77 else
78 {
79 std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl;
80 return 1u;
81 }
82 }
83
84// A macro that passed both the name and the value of the specified object to
85// the function above here.
86#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
87
88 // Equivalent to the dirty_stack() function from GCC Bug 33916,
89 // "Default constructor fails to initialize array members", reported in 2007 by
90 // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
91 void dirty_stack()
92 {
93 unsigned char array_on_stack[4096];
94 for (unsigned i = 0; i < sizeof(array_on_stack); ++i)
95 {
96 array_on_stack[i] = 0x11;
97 }
98 }
99
100}
101
102
103int main()
104{
105 dirty_stack();
106
107 // TODO More types may be added later.
108 const unsigned num_failures =
109 FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) +
110 FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>());
111
112#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
113 // One or more failures are expected.
114 return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
115#else
116 // No failures are expected.
117 return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
118#endif
119}