1 #ifndef BOOST_SERIALIZATION_STATIC_WARNING_HPP
2 #define BOOST_SERIALIZATION_STATIC_WARNING_HPP
4 // (C) Copyright Robert Ramey 2003. Jonathan Turkanis 2004.
5 // Use, modification and distribution is subject to the Boost Software
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // MS compatible compilers support #pragma once
8 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
12 // http://www.boost.org/LICENSE_1_0.txt)
14 // See http://www.boost.org/libs/static_assert for documentation.
18 15 June 2003 - Initial version.
19 31 March 2004 - improved diagnostic messages and portability
21 03 April 2004 - works on VC6 at class and namespace scope
22 - ported to DigitalMars
23 - static warnings disabled by default; when enabled,
24 uses pragmas to enable required compiler warnings
25 on MSVC, Intel, Metrowerks and Borland 5.x.
27 30 May 2004 - tweaked for msvc 7.1 and gcc 3.3
28 - static warnings ENabled by default; when enabled,
32 #include <boost/config.hpp>
36 // Makes use of the following warnings:
37 // 1. GCC prior to 3.3: division by zero.
38 // 2. BCC 6.0 preview: unreferenced local variable.
39 // 3. DigitalMars: returning address of local automatic variable.
40 // 4. VC6: class previously seen as struct (as in 'boost/mpl/print.hpp')
41 // 5. All others: deletion of pointer to incomplete type.
43 // The trick is to find code which produces warnings containing the name of
44 // a structure or variable. Details, with same numbering as above:
45 // 1. static_warning_impl<B>::value is zero iff B is false, so diving an int
46 // by this value generates a warning iff B is false.
47 // 2. static_warning_impl<B>::type has a constructor iff B is true, so an
48 // unreferenced variable of this type generates a warning iff B is false.
49 // 3. static_warning_impl<B>::type overloads operator& to return a dynamically
50 // allocated int pointer only is B is true, so returning the address of an
51 // automatic variable of this type generates a warning iff B is fasle.
52 // 4. static_warning_impl<B>::STATIC_WARNING is decalred as a struct iff B is
54 // 5. static_warning_impl<B>::type is incomplete iff B is false, so deleting a
55 // pointer to this type generates a warning iff B is false.
58 //------------------Enable selected warnings----------------------------------//
60 // Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. The
61 // only pragma which is absolutely necessary here is for Borland 5.x, since
62 // W8073 is disabled by default. If enabling selected warnings is considered
63 // unacceptable, this section can be replaced with:
64 // #if defined(__BORLANDC__) && (__BORLANDC__ <= 0x600)
68 # if defined(BOOST_MSVC)
69 # pragma warning(2:4150) // C4150: deletion of pointer to incomplete type 'type'.
70 # elif defined(BOOST_INTEL) && (defined(__WIN32__) || defined(WIN32))
71 # pragma warning(2:457) // #457: delete of pointer to incomplete class.
72 # elif defined(__BORLANDC__) && (__BORLANDC__ <= 0x600)
73 # pragma warn +stu // W8073: Undefined structure 'structure'.
74 # elif defined(__MWERKS__)
75 # pragma extended_errorcheck on // Enable 'extended error checking'.
78 //------------------Configure-------------------------------------------------//
79 # if defined(BOOST_INTEL)
81 # define BOOST_HAS_DESCRIPTIVE_DIVIDE_BY_ZERO_WARNING
82 # elif defined(__GNUC__) && !defined(BOOST_INTEL) // && (__GNUC__ * 100 + __GNUC_MINOR__ <= 302)
83 # define BOOST_HAS_DESCRIPTIVE_DIVIDE_BY_ZERO_WARNING
84 # elif defined(__DECCXX) // for Tru64
85 # define BOOST_HAS_DESCRIPTIVE_DIVIDE_BY_ZERO_WARNING
86 # elif defined(__DMC__)
87 # define BOOST_HAS_DESCRIPTIVE_RETURNING_ADDRESS_OF_TEMPORARY_WARNING
88 # elif defined(BOOST_MSVC) // && (BOOST_MSVC < 1300)
89 # define BOOST_NO_PREDEFINED_LINE_MACRO
90 # pragma warning(disable:4094) // C4094: untagged 'struct' declared no symbols
92 # define BOOST_HAS_DESCRIPTIVE_INCOMPLETE_TYPE_WARNING
95 //------------------Helper templates------------------------------------------//
98 namespace serialization
{
100 struct STATIC_WARNING
;
103 struct static_warning_impl
;
106 struct static_warning_impl
<false> {
108 #if !defined(BOOST_HAS_DESCRIPTIVE_UNREFERENCED_VARIABLE_WARNING) && \
109 !defined(BOOST_HAS_DESCRIPTIVE_RETURNING_ADDRESS_OF_TEMPORARY_WARNING)
110 typedef boost::serialization::STATIC_WARNING type
;
114 #if defined(BOOST_NO_PREDEFINED_LINE_MACRO)
115 struct STATIC_WARNING
{ };
120 struct static_warning_impl
<true> {
122 struct type
{ type() { } int* operator&() { return new int; } };
123 #if defined(BOOST_NO_PREDEFINED_LINE_MACRO)
124 class STATIC_WARNING
{ };
128 } // namespace serialization
131 //------------------Definition of BOOST_STATIC_WARNING------------------------//
133 #if defined(BOOST_HAS_DESCRIPTIVE_UNREFERENCED_VARIABLE_WARNING)
134 # define BOOST_STATIC_WARNING_IMPL(B) \
135 struct BOOST_JOIN(STATIC_WARNING, __LINE__) { \
137 ::boost::serialization::static_warning_impl<(bool)( B )>::type \
142 #elif defined(BOOST_HAS_DESCRIPTIVE_RETURNING_ADDRESS_OF_TEMPORARY_WARNING)
143 # define BOOST_STATIC_WARNING_IMPL(B) \
144 struct BOOST_JOIN(STATIC_WARNING, __LINE__) { \
146 ::boost::serialization::static_warning_impl<(bool)( B )>::type \
148 return &STATIC_WARNING; \
152 #elif defined(BOOST_HAS_DESCRIPTIVE_DIVIDE_BY_ZERO_WARNING)
153 # define BOOST_STATIC_WARNING_IMPL(B) \
154 struct BOOST_JOIN(STATIC_WARNING, __LINE__) { \
156 int STATIC_WARNING = 1; \
157 return STATIC_WARNING / \
158 boost::serialization::static_warning_impl<(bool)( B )>::value; } \
161 #elif defined(BOOST_NO_PREDEFINED_LINE_MACRO)
162 // VC6; __LINE__ macro broken when -ZI is used see Q199057, so
163 // non-conforming workaround is used.
164 # define BOOST_STATIC_WARNING_IMPL(B) \
165 struct BOOST_JOIN(STATIC_WARNING, __LINE__) { \
167 typedef boost::serialization::static_warning_impl<(bool)( B )> f; \
168 friend class f::STATIC_WARNING; \
172 #elif defined(BOOST_HAS_DESCRIPTIVE_INCOMPLETE_TYPE_WARNING)
173 # define BOOST_STATIC_WARNING_IMPL(B) \
174 struct BOOST_JOIN(STATIC_WARNING, __LINE__) { \
175 ::boost::serialization::static_warning_impl<(bool)( B )>::type* p; \
176 void f() { delete p; } \
179 #else // not defined for this compiler
180 # define BOOST_STATIC_WARNING_IMPL(B)
183 #ifndef BOOST_DISABLE_STATIC_WARNINGS
184 # define BOOST_STATIC_WARNING(B) BOOST_STATIC_WARNING_IMPL(B)
185 #else // #ifdef BOOST_ENABLE_STATIC_WARNINGS //-------------------------------//
186 # define BOOST_STATIC_WARNING(B) BOOST_STATIC_WARNING_IMPL(true)
189 #endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP