Ticket #3869: no_complete_value_initialization.patch

File no_complete_value_initialization.patch, 10.9 KB (added by niels_dekker, 13 years ago)

New proposed patch, adding BOOST_NO_COMPLETE_VALUE_INITIALIZATION. Replaces the old config_compiler.patch (Update: removed Boost.Test dependency, as suggested by John Maddock.)

  • boost/config/compiler/borland.hpp

     
    261261#  define BOOST_NO_VOID_RETURNS
    262262#endif
    263263
     264// Borland has not completely implemented value-initialization:
     265// http://qc.embarcadero.com/wc/qcmain.aspx?rc=51854
     266// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
     267#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     268
    264269#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__)
    265270
    266271
  • boost/config/compiler/codegear.hpp

     
    1919#endif
    2020//
    2121// versions check:
    22 // last known and checked version is 0x620
    23 #if (__CODEGEARC__ > 0x620)
     22// last known and checked version is 0x621
     23#if (__CODEGEARC__ > 0x621)
    2424#  if defined(BOOST_ASSERT_CONFIG)
    2525#     error "Unknown compiler version - please run the configure tests and report the results"
    2626#  else
     
    4141#endif
    4242
    4343// CodeGear C++ Builder 2010
    44 #if (__CODEGEARC__ <= 0x620)
     44#if (__CODEGEARC__ <= 0x621)
    4545#  define BOOST_NO_TYPENAME_WITH_CTOR    // Cannot use typename keyword when making temporaries of a dependant type
    4646#  define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
    4747#  define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
     
    159159#  define BOOST_NO_VOID_RETURNS
    160160#endif
    161161
     162// Codegear has not completely implemented value-initialization:
     163// http://qc.embarcadero.com/wc/qcmain.aspx?rc=51854
     164// Note: This issue is reported as fixed by build number 12.0.3140.16150
     165// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
     166#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     167
    162168#define BOOST_COMPILER "CodeGear C++ version " BOOST_STRINGIZE(__CODEGEARC__)
    163169
  • boost/config/compiler/gcc.hpp

     
    6969#  endif
    7070#endif
    7171
     72#if __GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )
     73// Previous versions of GCC did not completely implement value-initialization:
     74// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4)
     75// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4)
     76// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
     77#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     78#endif
     79
    7280#ifndef __EXCEPTIONS
    7381# define BOOST_NO_EXCEPTIONS
    7482#endif
  • boost/config/compiler/sunpro_cc.hpp

     
    7575#define BOOST_NO_TWO_PHASE_NAME_LOOKUP
    7676#define BOOST_NO_ADL_BARRIER
    7777
     78// The Sun compiler has not completely implemented value-initialization.
     79// Note: I do not know if this issue is there in all versions of the Sun compiler.
     80// (Niels Dekker, April 2010)
     81// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
     82#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     83
     84
    7885//
    7986// C++0x features
    8087//
  • boost/config/compiler/visualc.hpp

     
    9999#  define BOOST_NO_ADL_BARRIER
    100100#endif
    101101
     102// Microsoft Visual C++ has not completely implemented value-initialization:
     103// https://connect.microsoft.com/VisualStudio/feedback/details/100744
     104// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
     105#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     106
     107
    102108#if _MSC_VER <= 1500  || !defined(BOOST_STRICT_CONFIG) // 1500 == VC++ 9.0
    103109#  define BOOST_NO_INITIALIZER_LISTS
    104110#endif
  • libs/config/doc/macro_reference.qbk

     
    4949[[`BOOST_NO_AUTO_PTR`][Standard library][
    5050If the compiler / library supplies non-standard or broken `std::auto_ptr`.
    5151]]
     52[[`BOOST_NO_COMPLETE_VALUE_INITIALIZATION`][Compiler][
     53Compiler has not completely implemented value-initialization.
     54See also [@../../utility/value_init.htm#compiler_issues `utility/value_init.htm#compiler_issues`]
     55]]
    5256[[`BOOST_NO_CTYPE_FUNCTIONS`][Platform][
    5357The Platform does not provide functions for the character-classifying
    5458operations `<ctype.h>` and `<cctype>`, only macros.
  • libs/config/test/Jamfile.v2

     
    4646     [ run math_info.cpp : : : <test-info>always_show_run_output <toolset>borland:<runtime-link>static <toolset>borland:<link>static ]
    4747     [ run abi/abi_test.cpp abi/main.cpp ]
    4848     [ run limits_test.cpp ../../test/build//boost_test_exec_monitor ]
     49     [ run no_complete_value_initialization.cpp ]
    4950     [ run link/main.cpp link//link_test
    5051          : #args
    5152          : #input-files
  • libs/config/test/no_complete_value_initialization.cpp

     
     1//  Use, modification and distribution are subject to the
     2//  Boost Software License, Version 1.0. (See accompanying file
     3//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     4
     5//  See http://www.boost.org/libs/config for most recent version.
     6
     7//  MACRO:         BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     8//  TITLE:         No complete value-initialization
     9//  DESCRIPTION:   This macro must be defined, if and only if the compiler
     10//  does not to have implemented value-initialization completely.
     11//  See also boost/libs/utility/value_init.htm#compiler_issues
     12
     13#include <boost/config.hpp>
     14#include <cstdlib>
     15#include <iostream>
     16
     17namespace
     18{
     19  enum enum_type { negative_number = -1, magic_number = 42 };
     20
     21  // A POD struct.
     22  struct pod_struct
     23  {
     24    enum_type e;
     25    char c; 
     26    unsigned char uc; 
     27    short s;
     28    int i;
     29    unsigned u;
     30    long l;
     31    float f; 
     32    double d; 
     33    void* p;
     34  };
     35
     36  bool is_zero_initialized(const pod_struct& arg)
     37  {
     38    return
     39      arg.e == 0 &&
     40      arg.c == 0 &&
     41      arg.uc == 0 &&
     42      arg.s == 0 &&
     43      arg.i == 0 &&
     44      arg.u == 0 &&
     45      arg.l == 0 &&
     46      arg.f == 0 &&
     47      arg.d == 0 &&
     48      arg.p == 0;
     49  }
     50
     51  // A class that holds a "magic" enum value.
     52  class enum_holder
     53  {
     54    enum_type m_enum;
     55  public:
     56
     57    enum_holder()
     58    :
     59    m_enum(magic_number)
     60    {
     61    }
     62
     63    bool is_default() const
     64    {
     65      return m_enum == magic_number;
     66    }
     67  };
     68
     69
     70  // A class that is not a POD type.
     71  class non_pod_class
     72  {
     73  private:
     74    enum_holder m_enum_holder;
     75
     76  public:
     77    int i;
     78
     79    virtual bool is_value_initialized() const
     80    {
     81      return m_enum_holder.is_default() && i == 0;
     82    }
     83
     84    virtual ~non_pod_class() {}
     85  };
     86
     87  // The first argument (is_value_initializated) tells whether value initialization
     88  // has succeeded.
     89  // The second argument tells what expression was evaluated.
     90  bool is_true(bool is_value_initializated, const char *const expression)
     91  {
     92    if ( ! is_value_initializated )
     93    {
     94#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     95      std::cout
     96        << "Information: " << expression << " evaluated to false.\n"
     97        << "  Therefor BOOST_NO_COMPLETE_VALUE_INITIALIZATION is defined for this compiler."
     98        << std::endl;
     99#else
     100      std::cerr
     101        << "Error: " << expression << " evaluated to false.\n"
     102        << "  Please consider defining BOOST_NO_COMPLETE_VALUE_INITIALIZATION for this compiler."
     103        << std::endl;
     104#endif
     105    }
     106    return is_value_initializated;
     107  }
     108
     109#define IS_TRUE(value) is_true(value, #value)
     110#define IS_ZERO(value) is_true(value == 0, #value " == 0")
     111
     112  // The default constructor of this class initializes each of its
     113  // data members by means of an empty set of parentheses, and checks
     114  // whether each of them is value-initialized.
     115  class value_initializer
     116  {
     117  private:
     118    enum_holder m_enum_holder;
     119    enum_type m_enum;
     120    char m_char; 
     121    unsigned char m_unsigned_char; 
     122    short m_short;
     123    int m_int;
     124    unsigned m_unsigned;
     125    long m_long;
     126    float m_float; 
     127    double m_double; 
     128    void* m_ptr;
     129    pod_struct m_pod;
     130    pod_struct m_pod_array[2];
     131    non_pod_class m_non_pod;
     132    non_pod_class m_non_pod_array[2];
     133
     134  public:
     135    value_initializer()
     136    :
     137    m_enum_holder(),
     138    m_enum(),
     139    m_char(),
     140    m_unsigned_char(),
     141    m_short(),
     142    m_int(),
     143    m_unsigned(),
     144    m_long(),
     145    m_float(),
     146    m_double(),
     147    m_ptr(),
     148    m_pod(), 
     149    m_pod_array(),
     150    m_non_pod(),
     151    m_non_pod_array()
     152    {
     153    }
     154
     155    // Returns the number of failures.
     156    unsigned check() const
     157    {
     158      return
     159        (IS_TRUE( m_enum_holder.is_default() ) ? 0 : 1) +
     160        (IS_ZERO(m_enum) ? 0 : 1) +
     161        (IS_ZERO(m_char) ? 0 : 1) +
     162        (IS_ZERO(m_unsigned_char) ? 0 : 1) +
     163        (IS_ZERO(m_short) ? 0 : 1) +
     164        (IS_ZERO(m_int) ? 0 : 1) +
     165        (IS_ZERO(m_unsigned) ? 0 : 1) +
     166        (IS_ZERO(m_long) ? 0 : 1) +
     167        (IS_ZERO(m_float) ? 0 : 1) +
     168        (IS_ZERO(m_double) ? 0 : 1) +
     169        (IS_ZERO(m_ptr) ? 0 : 1) +
     170        (IS_TRUE( is_zero_initialized(m_pod) ) ? 0 : 1) +
     171        (IS_TRUE( m_non_pod.is_value_initialized() ) ? 0 : 1) +
     172        (IS_TRUE( is_zero_initialized(m_pod_array[0])
     173        && is_zero_initialized(m_pod_array[1]) ) ? 0 : 1) +
     174        (IS_TRUE( m_non_pod_array[0].is_value_initialized()
     175        && m_non_pod_array[1].is_value_initialized() ) ? 0 : 1);
     176
     177    }
     178  };
     179
     180}  // End of namespace.
     181
     182int main(int, char*[])
     183{
     184  // Check both value-initialization on the stack and on the heap:
     185  const unsigned num_failures_on_stack = value_initializer().check();
     186  const value_initializer* const ptr = new value_initializer();
     187  const unsigned num_failures_on_heap = ptr->check();
     188  delete ptr;
     189
     190  const bool completely_value_initialized =
     191    num_failures_on_stack == 0 && num_failures_on_heap == 0;
     192
     193#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
     194  return completely_value_initialized ? EXIT_FAILURE : EXIT_SUCCESS;
     195#else
     196  return completely_value_initialized ? EXIT_SUCCESS : EXIT_FAILURE;
     197#endif
     198}