boost_config 0.1.0

Boost C++ library boost_config packaged using Zanbil
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
//  (C) Copyright Niels Dekker 2010. 
//  Use, modification and distribution are subject to 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)

//  See http://www.boost.org/libs/config for most recent version.

//  MACRO:         BOOST_NO_COMPLETE_VALUE_INITIALIZATION
//  TITLE:         No complete value-initialization
//  DESCRIPTION:   The C++ compiler does not to have implemented value-initialization completely.
//                 See also boost/libs/utility/value_init.htm#compiler_issues

#include <iostream>

//  This test checks various forms of value-initialization:
//  - doing subobject initialization inside a constructor
//  - creating a temporary object by T()
//  - creating a heap object by doing new T()
//  It checks various DefaultConstructible types, including fundamental types,
//  enum, union, pointer types, array types, POD and non-POD class types. For
//  each type of object, a helper function is_value_initialized(const T&) tells 
//  whether the object is value-initialized.
//
//  Note: It appeared insufficient to just check a single POD and a single 
//  non-POD class type, because some compilers correctly value-initialize some
//  POD and some non-POD objects, while failing to value-initialize others.
//
//  The test returns the number of encountered value-initialization failures.
  
namespace boost_no_complete_value_initialization
{
  enum enum_type { negative_number = -1, magic_number = 42 };
  
  class incomplete_class;
  
  typedef int (*function_ptr_type)(int);
  typedef int (incomplete_class::*member_function_ptr_type)(int);

  // A POD struct.
  struct pod_struct
  {
    enum_type e;
    bool b;
    char c;
    unsigned char uc;
    short s;
    int i;
    unsigned u;
    long l;
    float f;
    double d;
    long double ld;
    void* p;
  };

  bool is_value_initialized(const pod_struct& arg)
  {
    return
      arg.b == 0 &&
      arg.e == 0 &&
      arg.c == 0 &&
      arg.uc == 0 &&
      arg.s == 0 &&
      arg.i == 0 &&
      arg.u == 0 &&
      arg.l == 0 &&
      arg.f == 0 &&
      arg.d == 0 &&
      arg.p == 0;
  }

  // A POD struct derived from another POD struct.
  struct derived_pod_struct: pod_struct
  {
    int derived_data;
  };

  bool is_value_initialized(const derived_pod_struct& arg)
  {
    const pod_struct& base_subobject = arg; 
    return arg.derived_data == 0 && is_value_initialized(base_subobject);
  }


  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;
  }


  // A struct, having a bit-field.
  struct bit_field_struct
  {
    bool b : 1;
    char c : 7;
    unsigned u: 8 * sizeof(unsigned) - 1;  
  };
  
  bool is_value_initialized(const bit_field_struct& arg)
  {
    return arg.b == false && arg.c == '\0'&& arg.u == 0U;
  }
  
  // A struct, having a function pointer.
  struct function_ptr_struct
  {
    function_ptr_type data;
  };

  bool is_value_initialized(const function_ptr_struct& arg)
  {
    return arg.data == 0;
  }

  // A struct, having a member function pointer.
  struct member_function_ptr_struct
  {
    member_function_ptr_type data;
  };

  bool is_value_initialized(const member_function_ptr_struct& arg)
  {
    return arg.data == 0;
  }

  struct int_pair_struct
  {
    int first;
    int second;
  };

  typedef int int_pair_struct::*ptr_to_member_type;

  struct ptr_to_member_struct
  {
    ptr_to_member_type data;
  };

  bool is_value_initialized(const ptr_to_member_struct& arg)
  {
    return arg.data == 0;
  }

  // A struct, having an int. Equivalent to the struct TData, from CodeGear bug
  // report 51854, "Value-initialization: POD struct should be zero-initialized",
  // reported by me (Niels Dekker, LKEB) in 2007:
  // http://qc.embarcadero.com/wc/qcmain.aspx?d=51854
  struct int_struct
  {
    int data;
  };

  bool is_value_initialized(const int_struct& arg)
  {
    return arg.data == 0;
  }


  // A struct, having an int_struct.
  struct int_struct_holder
  {
    int_struct data;
  };

  bool is_value_initialized(const int_struct_holder& arg)
  {
    return is_value_initialized(arg.data);
  }


  // A struct derived from int_struct.
  struct derived_int_struct: int_struct
  {
  };

  bool is_value_initialized(const derived_int_struct& arg)
  {
    return arg.data == 0;
  }


  struct char_array_struct
  {
    char data[42];
  };

  bool is_value_initialized(const char_array_struct& arg)
  {
    for ( unsigned i = 0; i < sizeof(arg.data); ++i)
    {
      if ( arg.data[i] != 0 )
      {
        return false;
      }
    }
    return true;
  }


  class private_int_holder
  {
  private:
    int m_data;

    friend bool is_value_initialized(const private_int_holder& arg)
    {
      return arg.m_data == 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
  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;
  }


  union pod_struct_and_int_union
  {
    pod_struct first;
    int second;
  };

  bool is_value_initialized(const pod_struct_and_int_union& arg)
  {
    // When a union is zero-initialized, its first non-static 
    // named data member is zero-initialized ([dcl.init]).
    return is_value_initialized(arg.first);
  }


  union int_and_pod_struct_union
  {
    int first;
    pod_struct second;
  };

  bool is_value_initialized(const int_and_pod_struct_union& arg)
  {
    return arg.first == 0;
  }


  // A class that holds a "magic" enum value.
  // Note: This is not a POD class, because it has a user-defined
  // default constructor.
  class enum_holder
  {
    enum_type m_enum;
  public:

    enum_holder()
    :
    m_enum(magic_number)
    {
    }

    bool is_value_initialized() const
    {
      return m_enum == magic_number;
    }
  };

  bool is_value_initialized(const enum_holder& arg)
  {
    return arg.is_value_initialized();
  }


  // An aggregate struct of a non-POD class and an int.
  // Similar to struct A from Microsoft Visual C++ bug report 100744,
  // "Value-initialization in new-expression", reported in 2005 by
  // Pavel Kuznetsov (MetaCommunications Engineering):
  // https://connect.microsoft.com/VisualStudio/feedback/details/100744
  struct enum_holder_and_int
  {
    enum_holder e;
    int i;
  };

  bool is_value_initialized(const enum_holder_and_int& arg)
  {
    return arg.e.is_value_initialized() && arg.i == 0;
  }

  class user_defined_copy_constructor_holder
  {
  public:
    int data;

    user_defined_copy_constructor_holder()
    :
    data(0)
    {
    }

    user_defined_copy_constructor_holder(const user_defined_copy_constructor_holder& arg)
    :
    data(arg.data)
    {
    }
  };

  // An aggregate struct that has a data member which has a user-defined
  // copy constructor and a data member of a scalar type.
  // Similar to struct B from Microsoft Visual C++ bug report 499606,
  // "Presence of copy constructor breaks member class initialization", 
  // reported in 2009 by Alex Vakulenko:
  // https://connect.microsoft.com/VisualStudio/feedback/details/499606
  struct user_defined_copy_constructor_holder_and_int
  {
    user_defined_copy_constructor_holder first;
    int second;
  };

  bool is_value_initialized(const user_defined_copy_constructor_holder_and_int& arg)
  {
    return arg.first.data == 0 && arg.second == 0;
  }


  // An class that has a private and a protected int data member.
  class private_and_protected_int
  {
  private:
    int private_int;
  protected:
    int protected_int;
  public:
    friend bool is_value_initialized(const private_and_protected_int& arg)
    {
      return arg.private_int == 0 && arg.protected_int == 0;
    }
  };


  class user_defined_destructor_holder
  {
  public:
    int i;
    ~user_defined_destructor_holder()
    {
    }
  };

  bool is_value_initialized(const user_defined_destructor_holder& arg)
  {
    return arg.i == 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;
  }


  // A class that is not a POD type.
  class non_pod_class
  {
  private:
    enum_holder m_enum_holder;

  public:
    int i;

    virtual bool is_value_initialized() const
    {
      return m_enum_holder.is_value_initialized() && i == 0;
    }

    virtual ~non_pod_class() {}
  };

  bool is_value_initialized(const non_pod_class& arg)
  {
    return arg.is_value_initialized();
  }


  typedef char _2d_char_array_type[3][4];

  bool is_value_initialized(const _2d_char_array_type& arg)
  {
    for(unsigned i = 0; i < sizeof(_2d_char_array_type); ++i)
    {
      if ((*arg)[i] != 0)
      {
        return false;
      }
    }
    return true;
  }

  typedef char _3d_char_array_type[5][6][7];

  bool is_value_initialized(const _3d_char_array_type& arg)
  {
    for(unsigned i = 0; i < sizeof(_3d_char_array_type); ++i)
    {
      if ((**arg)[i] != 0)
      {
        return false;
      }
    }
    return true;
  }



  // Tells whether an object of a scalar type T is value-initialized.
  template <class T>
  bool is_value_initialized(const T& arg)
  {
    return arg == 0;
  }


  // Wraps a heap object that it has allocated by doing new T().
  template <class T>
  class heap_object_wrapper
  {
  private:
    T* const m_ptr;

    // The following function is intentionally left unimplemented
    // (as if deleted, "= delete", in C++0x):
    void operator=(heap_object_wrapper);

  public:
    heap_object_wrapper()
      :
    m_ptr(new T())
    {
    }

    ~heap_object_wrapper()
    {
      delete m_ptr;
    }

    // The copy-constructor is intentionally left unimplemented.
    heap_object_wrapper(const heap_object_wrapper&);

    bool is_wrapped_object_value_initialized() const
    {
      return (m_ptr != 0) && is_value_initialized(*m_ptr);
    }
  };

  template <class T>
  bool is_value_initialized(const heap_object_wrapper<T>& arg)
  {
    return arg.is_wrapped_object_value_initialized();
  }


  // 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 <class T>
  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)


  // value_initializer initializes each of its data members by means
  // of an empty set of parentheses, and allows checking whether
  // each of them is indeed value-initialized, as specified by 
  // the C++ Standard ([dcl.init]).
  //
  // Note: its base class, int_struct, is there to try to reproduce GCC Bug 30111,
  // "Value-initialization of POD base class doesn't initialize members", reported
  // by Jonathan Wakely in 2006: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
  class value_initializer: private int_struct
  {
  private:
    enum_holder m_enum_holder;
    enum_holder m_enum_holder_array[2];
    enum_type m_enum;
    enum_type m_enum_array[2];
    bool m_bool;
    bool m_bool_array[2];
    char m_char;
    char m_char_array[2];
    _2d_char_array_type m_2d_char_array;
    _3d_char_array_type m_3d_char_array;
    unsigned char m_unsigned_char;
    unsigned char m_unsigned_char_array[2];
    short m_short;
    short m_short_array[2];
    int m_int;
    int m_int_array[2];
    unsigned m_unsigned;
    unsigned m_unsigned_array[2];
    long m_long;
    long m_long_array[2];
    float m_float;
    float m_float_array[2];
    double m_double;
    double m_double_array[2];
    long double m_long_double;
    long double m_long_double_array[2];
    void* m_void_ptr;
    void* m_void_ptr_array[2];
    function_ptr_type m_function_ptr;
    function_ptr_type m_function_ptr_array[2];
    function_ptr_struct m_function_ptr_struct;
    function_ptr_struct m_function_ptr_struct_array[2];
    member_function_ptr_type m_member_function_ptr;
    member_function_ptr_type m_member_function_ptr_array[2];
    member_function_ptr_struct m_member_function_ptr_struct;
    member_function_ptr_struct m_member_function_ptr_struct_array[2];
    ptr_to_member_type  m_ptr_to_member;
    ptr_to_member_type  m_ptr_to_member_array[2];
    ptr_to_member_struct m_ptr_to_member_struct;
    ptr_to_member_struct m_ptr_to_member_struct_array[2];
    bit_field_struct m_bit_field_struct;
    bit_field_struct m_bit_field_struct_array[2];
    int_struct m_int_struct;
    int_struct m_int_struct_array[2];
    int_struct m_int_struct_holder;
    int_struct m_int_struct_holder_array[2];
    pod_struct m_pod_struct;
    pod_struct m_pod_struct_array[2];
    derived_pod_struct m_derived_pod_struct;
    derived_pod_struct m_derived_pod_struct_array[2];
    derived_struct m_derived_struct;
    derived_struct m_derived_struct_array[2];
    derived_int_struct m_derived_int_struct;
    derived_int_struct m_derived_int_struct_array[2];
    private_int_holder m_private_int_holder;
    private_int_holder m_private_int_holder_array[2];
    char_array_struct m_char_array_struct;
    char_array_struct m_char_array_struct_array[2];
    private_int_array_pair m_private_int_array_pair;
    private_int_array_pair m_private_int_array_pair_array[2];
    enum_holder_and_int m_enum_holder_and_int;
    enum_holder_and_int m_enum_holder_and_int_array[2];
    private_and_protected_int m_private_and_protected_int;
    private_and_protected_int m_private_and_protected_int_array[2];
    user_defined_copy_constructor_holder_and_int m_user_defined_copy_constructor_holder_and_int;
    user_defined_copy_constructor_holder_and_int m_user_defined_copy_constructor_holder_and_int_array[2];
    user_defined_destructor_holder m_user_defined_destructor_holder;
    user_defined_destructor_holder m_user_defined_destructor_holder_array[2];
    virtual_destructor_holder m_virtual_destructor_holder;
    virtual_destructor_holder m_virtual_destructor_holder_array[2];
    non_pod_class m_non_pod;
    non_pod_class m_non_pod_array[2];
    pod_struct_and_int_union m_pod_struct_and_int_union;
    pod_struct_and_int_union m_pod_struct_and_int_union_array[2];
    int_and_pod_struct_union m_int_and_pod_struct_union;
    int_and_pod_struct_union m_int_and_pod_struct_union_array[2];

  public:
    // Default constructor. Tries to value-initialize its base subobject and all
    // of its data.members.
    value_initializer()
    :
    // Note: CodeGear/Borland may produce a warning, W8039, for each data member
    // whose type is an array type, saying "Constructor initializer list ignored".
    // If it does, it probably won't value-initialize those arrays, as reported
    // by me (Niels Dekker, LKEB) in 2010, report 83751, "Value-initialization:
    // arrays should have each element value-initialized",
    // http://qc.embarcadero.com/wc/qcmain.aspx?d=83751
    // On the other hand, Microsoft Visual C++ may produce warnings of type C4351,
    // saying "new behavior: elements of array '...' will be default initialized",
    // which is actually the right behavior!
    int_struct(),
    m_enum_holder(),
    m_enum_holder_array(),
    m_enum(),
    m_enum_array(),
    m_bool(),
    m_bool_array(),
    m_char(),
    m_char_array(),
    m_2d_char_array(),
    m_3d_char_array(),
    m_unsigned_char(),
    m_unsigned_char_array(),
    m_short(),
    m_short_array(),
    m_int(),
    m_int_array(),
    m_unsigned(),
    m_unsigned_array(),
    m_long(),
    m_long_array(),
    m_float(),
    m_float_array(),
    m_double(),
    m_double_array(),
    m_long_double(),
    m_long_double_array(),
    m_void_ptr(),
    m_void_ptr_array(),
    m_function_ptr(),
    m_function_ptr_array(),
    m_function_ptr_struct(),
    m_function_ptr_struct_array(),
    m_member_function_ptr(),
    m_member_function_ptr_array(),
    m_member_function_ptr_struct(),
    m_member_function_ptr_struct_array(),
    m_ptr_to_member(),
    m_ptr_to_member_array(),
    m_ptr_to_member_struct(),
    m_ptr_to_member_struct_array(),
    m_bit_field_struct(),
    m_bit_field_struct_array(),
    m_int_struct(),
    m_int_struct_array(),
    m_int_struct_holder(),
    m_int_struct_holder_array(),
    m_pod_struct(),
    m_pod_struct_array(),
    m_derived_pod_struct(),
    m_derived_pod_struct_array(),
    m_derived_struct(),
    m_derived_struct_array(),
    m_derived_int_struct(),
    m_derived_int_struct_array(),
    m_private_int_holder(),
    m_private_int_holder_array(),
    m_char_array_struct(),
    m_char_array_struct_array(),
    m_private_int_array_pair(),
    m_private_int_array_pair_array(),
    m_enum_holder_and_int(),
    m_enum_holder_and_int_array(),
    m_private_and_protected_int(),
    m_private_and_protected_int_array(),
    m_user_defined_copy_constructor_holder_and_int(),
    m_user_defined_copy_constructor_holder_and_int_array(),
    m_user_defined_destructor_holder(),
    m_user_defined_destructor_holder_array(),
    m_virtual_destructor_holder(),
    m_virtual_destructor_holder_array(),
    m_non_pod(),
    m_non_pod_array(),
    m_pod_struct_and_int_union(),
    m_pod_struct_and_int_union_array(),
    m_int_and_pod_struct_union(),
    m_int_and_pod_struct_union_array()
    {
    }

    // Returns the number of failures.
    unsigned check_value_initialization_of_subobjects() const
    {
      const unsigned num_failures = 
        FAILED_TO_VALUE_INITIALIZE(int_struct::data) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_holder) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_holder_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_holder_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_enum) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_bool) +
        FAILED_TO_VALUE_INITIALIZE(m_bool_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_bool_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_char) +
        FAILED_TO_VALUE_INITIALIZE(m_char_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_char_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_2d_char_array) +
        FAILED_TO_VALUE_INITIALIZE(m_3d_char_array) +
        FAILED_TO_VALUE_INITIALIZE(m_unsigned_char) +
        FAILED_TO_VALUE_INITIALIZE(m_unsigned_char_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_unsigned_char_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_short) +
        FAILED_TO_VALUE_INITIALIZE(m_short_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_short_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_int) +
        FAILED_TO_VALUE_INITIALIZE(m_int_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_unsigned) +
        FAILED_TO_VALUE_INITIALIZE(m_unsigned_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_unsigned_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_long) +
        FAILED_TO_VALUE_INITIALIZE(m_long_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_long_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_float) +
        FAILED_TO_VALUE_INITIALIZE(m_float_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_float_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_double) +
        FAILED_TO_VALUE_INITIALIZE(m_double_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_double_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_long_double) +
        FAILED_TO_VALUE_INITIALIZE(m_long_double_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_long_double_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_void_ptr) +
        FAILED_TO_VALUE_INITIALIZE(m_void_ptr_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_void_ptr_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_function_ptr) +
        FAILED_TO_VALUE_INITIALIZE(m_function_ptr_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_function_ptr_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_function_ptr_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_function_ptr_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_function_ptr_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr) +
        FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member) +
        FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_bit_field_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_bit_field_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_bit_field_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_int_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_struct_holder) +
        FAILED_TO_VALUE_INITIALIZE(m_int_struct_holder_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_struct_holder_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_pod_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_pod_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_pod_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_pod_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_pod_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_pod_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_private_int_holder) +
        FAILED_TO_VALUE_INITIALIZE(m_private_int_holder_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_private_int_holder_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_char_array_struct) +
        FAILED_TO_VALUE_INITIALIZE(m_char_array_struct_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_char_array_struct_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair) +
        FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_private_and_protected_int) +
        FAILED_TO_VALUE_INITIALIZE(m_private_and_protected_int_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_private_and_protected_int_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_user_defined_copy_constructor_holder_and_int) +
        FAILED_TO_VALUE_INITIALIZE(m_user_defined_copy_constructor_holder_and_int_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_user_defined_copy_constructor_holder_and_int_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_user_defined_destructor_holder) +
        FAILED_TO_VALUE_INITIALIZE(m_user_defined_destructor_holder_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_user_defined_destructor_holder_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_virtual_destructor_holder) +
        FAILED_TO_VALUE_INITIALIZE(m_virtual_destructor_holder_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_virtual_destructor_holder_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_non_pod) +
        FAILED_TO_VALUE_INITIALIZE(m_non_pod_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_non_pod_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_pod_struct_and_int_union) +
        FAILED_TO_VALUE_INITIALIZE(m_pod_struct_and_int_union_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_pod_struct_and_int_union_array[1]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_and_pod_struct_union) +
        FAILED_TO_VALUE_INITIALIZE(m_int_and_pod_struct_union_array[0]) +
        FAILED_TO_VALUE_INITIALIZE(m_int_and_pod_struct_union_array[1]);
      return num_failures;
    }
  };

  // Checks value-initialization of a number of small temporary objects.
  // Returns the number of failures.
  unsigned check_value_initialization_of_temporaries()
  {
    typedef long double long_double_type;
    typedef unsigned char unsigned_char_type;
    typedef void* void_ptr_type;

    const unsigned num_failures = 
      FAILED_TO_VALUE_INITIALIZE(enum_holder()) +
      FAILED_TO_VALUE_INITIALIZE(enum_type()) +
      FAILED_TO_VALUE_INITIALIZE(bool()) +
      FAILED_TO_VALUE_INITIALIZE(char()) +
      FAILED_TO_VALUE_INITIALIZE(unsigned_char_type()) +
      FAILED_TO_VALUE_INITIALIZE(short()) +
      FAILED_TO_VALUE_INITIALIZE(int()) +
      FAILED_TO_VALUE_INITIALIZE(unsigned()) +
      FAILED_TO_VALUE_INITIALIZE(long()) +
      FAILED_TO_VALUE_INITIALIZE(float()) +
      FAILED_TO_VALUE_INITIALIZE(double()) +
      FAILED_TO_VALUE_INITIALIZE(long_double_type()) +
      FAILED_TO_VALUE_INITIALIZE(void_ptr_type()) +
      FAILED_TO_VALUE_INITIALIZE(bit_field_struct()) +
      FAILED_TO_VALUE_INITIALIZE(function_ptr_type()) +
      FAILED_TO_VALUE_INITIALIZE(function_ptr_struct()) +
      FAILED_TO_VALUE_INITIALIZE(member_function_ptr_type()) +
      FAILED_TO_VALUE_INITIALIZE(member_function_ptr_struct()) +
      FAILED_TO_VALUE_INITIALIZE(ptr_to_member_type()) +
      FAILED_TO_VALUE_INITIALIZE(ptr_to_member_struct()) +
      FAILED_TO_VALUE_INITIALIZE(int_struct()) +
      FAILED_TO_VALUE_INITIALIZE(int_struct_holder()) +
      FAILED_TO_VALUE_INITIALIZE(pod_struct()) +
      FAILED_TO_VALUE_INITIALIZE(derived_pod_struct()) +
      FAILED_TO_VALUE_INITIALIZE(derived_struct()) +
      FAILED_TO_VALUE_INITIALIZE(derived_int_struct()) +
      FAILED_TO_VALUE_INITIALIZE(private_int_holder()) +
      FAILED_TO_VALUE_INITIALIZE(char_array_struct()) +
      FAILED_TO_VALUE_INITIALIZE(private_int_array_pair()) +
      // IBM's XL V10.1.0.0 may fail to value-initialize a temporary of a non-POD
      // type like enum_holder_and_int, virtual_destructor_holder, or non_pod_class, 
      // as appeared at the Boost Config/trunk regression page in April 2010.
      // Michael Wong (IBM Canada Ltd) confirmed the issue to me (Niels Dekker, LKEB),
      // and gave it high priority.
      FAILED_TO_VALUE_INITIALIZE(enum_holder_and_int()) +
      FAILED_TO_VALUE_INITIALIZE(private_and_protected_int()) +
      FAILED_TO_VALUE_INITIALIZE(user_defined_copy_constructor_holder_and_int()) +
      // The following line, doing user_defined_destructor_holder(), causes  
      // a compilation error on Embarcadero 2010 (Borland/CodeGear 6.21), 
      // as reported by me (Niels Dekker, LKEB) in 2010, bug report 83851,
      // "Value-initialized temporary triggers internal backend error C1798",
      // http://qc.embarcadero.com/wc/qcmain.aspx?d=83851
      FAILED_TO_VALUE_INITIALIZE(user_defined_destructor_holder()) +
      FAILED_TO_VALUE_INITIALIZE(virtual_destructor_holder()) +
      FAILED_TO_VALUE_INITIALIZE(non_pod_class()) +
      FAILED_TO_VALUE_INITIALIZE(pod_struct_and_int_union()) +
      FAILED_TO_VALUE_INITIALIZE(int_and_pod_struct_union());
    return num_failures;
  }

  // Checks value-initialization of small heap objects.
  // Returns the number of failures.
  unsigned check_value_initialization_of_heap_objects()
  {
    const unsigned num_failures = 
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_holder>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_type>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<bool>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<char>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<unsigned char>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<short>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<unsigned>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<long>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<float>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<double>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<long double>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<void*>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<function_ptr_type>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<function_ptr_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<member_function_ptr_type>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<member_function_ptr_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<ptr_to_member_type>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<ptr_to_member_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<bit_field_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<pod_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_pod_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_int_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<char_array_struct>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_int_holder>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_int_array_pair>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_holder_and_int>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_and_protected_int>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<user_defined_copy_constructor_holder_and_int>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<user_defined_destructor_holder>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<virtual_destructor_holder>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<non_pod_class>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<pod_struct_and_int_union>() ) +
      FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_and_pod_struct_union>() );
    return num_failures;
  }

  // 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[sizeof(value_initializer) + 256];
    for (unsigned i = 0; i < sizeof(array_on_stack); ++i)
    {
      array_on_stack[i] = 0x11;
    }
  }


  // Checks value-initialization of the subobjects of a temporary object, 
  // an object on the stack, an object on the heap; furthermore it checks 
  // value-initialization of a number of smaller temporary objects and 
  // heap objects.
  int test()
  {
    unsigned total_num_failures = 0;

    dirty_stack();
    const unsigned num_failures_of_subobjects_of_a_temporary =
      value_initializer().check_value_initialization_of_subobjects();

    total_num_failures += num_failures_of_subobjects_of_a_temporary;
    if ( total_num_failures > 0 )
    {
      std::cout << "- Number of subobject initialization failures of a temporary: "
        << num_failures_of_subobjects_of_a_temporary << std::endl;
    }
    dirty_stack();
    value_initializer object_on_stack;
    const unsigned num_failures_of_subobjects_on_stack =
      object_on_stack.check_value_initialization_of_subobjects();

    total_num_failures += num_failures_of_subobjects_on_stack;
    if ( total_num_failures > 0 )
    {
      std::cout << "- Number of subobject initialization failures on the stack: "
        << num_failures_of_subobjects_on_stack << std::endl;
    }
    const value_initializer* const ptr = new value_initializer();
    const unsigned num_failures_of_subobjects_on_heap = ptr->check_value_initialization_of_subobjects();
    delete ptr;

    total_num_failures += num_failures_of_subobjects_on_heap;
    if ( total_num_failures > 0 )
    {
      std::cout << "- Number of subobject initialization failures on the heap: "
        << num_failures_of_subobjects_on_heap << std::endl;
    }

    dirty_stack();
    const unsigned num_failures_of_temporaries = check_value_initialization_of_temporaries();

    total_num_failures += num_failures_of_temporaries;
    if ( total_num_failures > 0 )
    {
      std::cout << "- Number of initialization failures of temporary objects: "
        << num_failures_of_temporaries << std::endl;
    }

    const unsigned num_failures_of_heap_objects = check_value_initialization_of_heap_objects();

    total_num_failures += num_failures_of_heap_objects;
    if ( total_num_failures > 0 )
    {
      std::cout << "- Number of failures of heap objects: "
        << num_failures_of_heap_objects << std::endl;
    }

    if ( total_num_failures > 0 )
    {
      std::cout << "-- Total number of initialization failures ("
        << num_failures_of_subobjects_of_a_temporary << '+'
        << num_failures_of_subobjects_on_stack << '+'
        << num_failures_of_subobjects_on_heap << '+'
        << num_failures_of_temporaries << '+'
        << num_failures_of_heap_objects << "): "
        << total_num_failures
        << "\nDetected by boost_no_complete_value_initialization::test() revision 32."
        << std::endl;
    }
    return static_cast<int>(total_num_failures);
  }

}  // End of namespace.