source: NonGTP/Boost/boost/static_warning.hpp @ 857

Revision 857, 7.8 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef BOOST_STATIC_WARNING_HPP
2#define BOOST_STATIC_WARNING_HPP
3
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)
9# pragma once
10#endif
11
12// http://www.boost.org/LICENSE_1_0.txt)
13
14//  See http://www.boost.org/libs/static_assert for documentation.
15
16/*
17 Revision history:
18   15 June  2003 - Initial version.
19   31 March 2004 - improved diagnostic messages and portability
20                   (Jonathan Turkanis)
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.
26                   (Jonathan Turkanis)
27   30 May 2004   - tweaked for msvc 7.1 and gcc 3.3
28                 - static warnings ENabled by default; when enabled,
29                   (Robert Ramey)
30*/
31
32#include <boost/config.hpp>
33
34//
35// Implementation
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.
42//
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
53//    false.
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.
56//
57
58//------------------Enable selected warnings----------------------------------//
59
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)
65//    pragma warn +stu
66//   #endif
67
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'.
76# endif
77
78//------------------Configure-------------------------------------------------//
79
80# if defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)
81#  define BOOST_HAS_DESCRIPTIVE_UNREFERENCED_VARIABLE_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(__DMC__)
85#  define BOOST_HAS_DESCRIPTIVE_RETURNING_ADDRESS_OF_TEMPORARY_WARNING
86# elif defined(BOOST_MSVC) // && (BOOST_MSVC < 1300)
87#  define BOOST_NO_PREDEFINED_LINE_MACRO
88#  pragma warning(disable:4094) // C4094: untagged 'stuct' declared no symbols
89#endif
90
91//------------------Helper templates------------------------------------------//
92
93namespace boost {
94
95struct STATIC_WARNING;
96
97template<bool>
98struct static_warning_impl;
99
100template<>
101struct static_warning_impl<false> {
102    enum { value = 0 };
103    #if !defined(BOOST_HAS_DESCRIPTIVE_UNREFERENCED_VARIABLE_WARNING) && \
104        !defined(BOOST_HAS_DESCRIPTIVE_RETURNING_ADDRESS_OF_TEMPORARY_WARNING)
105        typedef boost::STATIC_WARNING type;
106    #else
107        typedef int type;
108    #endif
109    #if defined(BOOST_NO_PREDEFINED_LINE_MACRO)
110        struct STATIC_WARNING { };
111    #endif
112};
113
114template<>
115struct static_warning_impl<true> {
116    enum { value = 1 };
117    struct type { type() { } int* operator&() { return new int; } };
118    #if defined(BOOST_NO_PREDEFINED_LINE_MACRO)
119        class STATIC_WARNING { };
120    #endif
121};
122
123} // namespace boost
124
125//------------------Definition of BOOST_STATIC_WARNING------------------------//
126
127#if defined(BOOST_HAS_DESCRIPTIVE_UNREFERENCED_VARIABLE_WARNING)
128#    define BOOST_STATIC_WARNING_IMPL(B)                   \
129     struct BOOST_JOIN(STATIC_WARNING, __LINE__) {         \
130       void f() {                                          \
131           ::boost::static_warning_impl<(bool)( B )>::type \
132           STATIC_WARNING;                                 \
133       }                                                   \
134     }                                                     \
135     /**/
136#elif defined(BOOST_HAS_DESCRIPTIVE_RETURNING_ADDRESS_OF_TEMPORARY_WARNING)
137#    define BOOST_STATIC_WARNING_IMPL(B)                        \
138     struct BOOST_JOIN(STATIC_WARNING, __LINE__) {              \
139        int* f() {                                              \
140            ::boost::static_warning_impl<(bool)( B )>::type     \
141            STATIC_WARNING;                                     \
142            return &STATIC_WARNING;                             \
143        }                                                       \
144     }                                                          \
145     /**/
146#elif defined(BOOST_HAS_DESCRIPTIVE_DIVIDE_BY_ZERO_WARNING)
147#    define BOOST_STATIC_WARNING_IMPL(B)                             \
148     struct BOOST_JOIN(STATIC_WARNING, __LINE__) {                   \
149         int f() { int STATIC_WARNING = 1;                           \
150                   return STATIC_WARNING /                           \
151                   boost::static_warning_impl<(bool)( B )>::value; } \
152     }                                                               \
153     /**/
154#elif defined(BOOST_NO_PREDEFINED_LINE_MACRO)
155     // VC6; __LINE__ macro broken when -ZI is used see Q199057, so
156     // non-conforming workaround is used.
157#    define BOOST_STATIC_WARNING_IMPL(B)                       \
158     struct {                                                  \
159        struct S {                                             \
160            typedef boost::static_warning_impl<(bool)( B )> f; \
161            friend class f::STATIC_WARNING;                    \
162        };                                                     \
163     }                                                         \
164     /**/
165#else // Deletion of pointer to incomplete type.
166#    define BOOST_STATIC_WARNING_IMPL(B)                     \
167     struct BOOST_JOIN(STATIC_WARNING, __LINE__) {           \
168         ::boost::static_warning_impl<(bool)( B )>::type* p; \
169         void f() { delete p; }                              \
170     }                                                       \
171     /**/
172#endif
173
174#ifndef BOOST_DISABLE_STATIC_WARNINGS
175# define BOOST_STATIC_WARNING(B) BOOST_STATIC_WARNING_IMPL(B)
176#else // #ifdef BOOST_ENABLE_STATIC_WARNINGS //-------------------------------//
177# define BOOST_STATIC_WARNING(B) BOOST_STATIC_WARNING_IMPL(true)
178#endif
179
180#endif // BOOST_STATIC_WARNING_HPP
Note: See TracBrowser for help on using the repository browser.