00001 /* -*- mode:C++; c-basic-offset:4 -*- 00002 Shore-MT -- Multi-threaded port of the SHORE storage manager 00003 00004 Copyright (c) 2007-2009 00005 Data Intensive Applications and Systems Labaratory (DIAS) 00006 Ecole Polytechnique Federale de Lausanne 00007 00008 All Rights Reserved. 00009 00010 Permission to use, copy, modify and distribute this software and 00011 its documentation is hereby granted, provided that both the 00012 copyright notice and this permission notice appear in all copies of 00013 the software, derivative works or modified versions, and any 00014 portions thereof, and that both notices appear in supporting 00015 documentation. 00016 00017 This code is distributed in the hope that it will be useful, but 00018 WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS 00020 DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER 00021 RESULTING FROM THE USE OF THIS SOFTWARE. 00022 */ 00023 00024 /*<std-header orig-src='shore' incl-file-exclusion='W_WORKAROUND_H'> 00025 00026 $Id: w_workaround.h,v 1.60 2010/06/18 21:22:48 nhall Exp $ 00027 00028 SHORE -- Scalable Heterogeneous Object REpository 00029 00030 Copyright (c) 1994-99 Computer Sciences Department, University of 00031 Wisconsin -- Madison 00032 All Rights Reserved. 00033 00034 Permission to use, copy, modify and distribute this software and its 00035 documentation is hereby granted, provided that both the copyright 00036 notice and this permission notice appear in all copies of the 00037 software, derivative works or modified versions, and any portions 00038 thereof, and that both notices appear in supporting documentation. 00039 00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY 00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS 00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND 00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 00044 00045 This software was developed with support by the Advanced Research 00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by 00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518. 00048 Further funding for this work was provided by DARPA through 00049 Rome Research Laboratory Contract No. F30602-97-2-0247. 00050 00051 */ 00052 00053 #ifndef W_WORKAROUND_H 00054 #define W_WORKAROUND_H 00055 00056 #include "w_defines.h" 00057 00058 /* -- do not edit anything above this line -- </std-header>*/ 00059 00060 /**\file w_workaround.h 00061 * Macros that allow workarounds for different compilers. 00062 */ 00063 00064 00065 #ifdef __GNUC__ 00066 00067 /* Mechanism to make disjoint gcc numbering appear linear for comparison 00068 purposes. Without this all the Shore gcc hacks break when a new major 00069 number is encountered. 00070 */ 00071 00072 #define W_GCC_VER(major,minor) (((major) << 16) + (minor)) 00073 00074 #ifndef __GNUC_MINOR__ /* gcc-1.something -- No minor version number */ 00075 #define W_GCC_THIS_VER W_GCC_VER(__GNUC__,0) 00076 #else 00077 #define W_GCC_THIS_VER W_GCC_VER(__GNUC__,__GNUC_MINOR__) 00078 #endif 00079 00080 00081 /* true if THIS gcc version is <= the specified major,minor prerequisite */ 00082 #define W_GCC_PREREQ(major,minor) \ 00083 (W_GCC_THIS_VER >= W_GCC_VER(major,minor)) 00084 00085 #if W_GCC_THIS_VER < W_GCC_VER(2,5) 00086 /* XXX all the following tests assume this filter is used */ 00087 #error This software requires gcc 2.5.x or a later release. 00088 #error Gcc 2.6.0 is preferred. 00089 #endif 00090 00091 00092 #if W_GCC_THIS_VER < W_GCC_VER(2,6) 00093 00094 /* 00095 * G++ also has a bug in calling the destructor of a template 00096 */ 00097 # define GNUG_BUG_2 1 00098 00099 /* 00100 * G++ seems to have a problem calling ::operator delete 00101 */ 00102 # define GNUG_BUG_3 1 00103 00104 /* 00105 * G++ version 2.4.5 has problems with templates that don't have 00106 * destructors explicitly defined. It also seems to have problems 00107 * with classes used to instantiate templates if those classes 00108 * do not have destructors. 00109 */ 00110 # define GNUG_BUG_7 1 00111 00112 /* bug #8: 00113 * gcc include files don't define signal() as in ANSI C. 00114 * we need to get around that 00115 */ 00116 # define GNUG_BUG_8 1 00117 00118 #endif /* gcc < 2.6 */ 00119 00120 /* 00121 * #12 00122 * This is a bug in parsing specific to gcc 2.6.0. 00123 * The compiler misinterprets: 00124 * int(j) 00125 * to be a declaration of j as an int rather than the correct 00126 * interpretation as a cast of j to an int. This shows up in 00127 * statements like: 00128 * istrstream(c) >> i; 00129 */ 00130 00131 /* see below for more info on GNUG_BUG_12 */ 00132 #define GNUG_BUG_12(arg) arg 00133 #if W_GCC_THIS_VER > W_GCC_VER(2,5) 00134 # undef GNUG_BUG_12 00135 # define GNUG_BUG_12(arg) (arg) 00136 #endif 00137 00138 #if W_GCC_THIS_VER > W_GCC_VER(2,5) 00139 /* 00140 * GNU 2.6.0 : template functions that are 00141 * not member functions don't get exported from the 00142 * implementation file. 00143 */ 00144 #define GNUG_BUG_13 1 00145 00146 /* 00147 * Cannot explicitly instantiate function templates. 00148 */ 00149 #define GNUG_BUG_14 1 00150 #endif 00151 00152 #if W_GCC_THIS_VER > W_GCC_VER(2,6) 00153 /* gcc 2.7.2 has bogus warning messages; it doesn't inherit pointer 00154 properties correctly */ 00155 #define GNUG_BUG_15 1 00156 #endif 00157 00158 /* Gcc 64 bit integer math incorrectly optimizes range comparisons such as 00159 if (i64 < X || i64 > Y) 00160 zzz; 00161 This should be re-examined when we upgrade to 2.8, perhaps it is fixed and 00162 we can make this a 2.7 dependency. 00163 */ 00164 #define GNUG_BUG_16 00165 00166 /****************************************************************************** 00167 * 00168 * Migration to standard C++ 00169 * 00170 ******************************************************************************/ 00171 #if W_GCC_THIS_VER >= W_GCC_VER(2,90) 00172 /* 00173 * EGCS is 2.90 (which really screws up any attempt to fix 00174 * things based on __GNUC_MINOR__ and __GNUC__ 00175 * and egcs does not define any different macro to identify itself. 00176 */ 00177 #endif 00178 00179 #if W_GCC_THIS_VER < W_GCC_VER(2,8) 00180 00181 # define BIND_FRIEND_OPERATOR_PART_1(TYP,L,TMPLa,TMPLb) /**/ 00182 # define BIND_FRIEND_OPERATOR_PART_1B(TYP1,TYP3,TYP2,TMPLa,TMPLc,TMPLb) /**/ 00183 # define BIND_FRIEND_OPERATOR_PART_2(TYP) /**/ 00184 # define BIND_FRIEND_OPERATOR_PART_2B(TYP1,TYP2) /**/ 00185 00186 # else 00187 00188 # define BIND_FRIEND_OPERATOR_PART_1(TYP,L,TMPLa,TMPLb) \ 00189 template <class TYP, class L> \ 00190 ostream & operator<<(ostream&o, const TMPLa,TMPLb& l); 00191 00192 # define BIND_FRIEND_OPERATOR_PART_1B(TYP1,TYP3, TYP2,TMPLa,TMPLc,TMPLb) \ 00193 template <class TYP1, class TYP3, class TYP2> \ 00194 ostream & operator<<(ostream&o, const TMPLa,TMPLc,TMPLb& l); 00195 00196 # define BIND_FRIEND_OPERATOR_PART_2(TYP, L)\ 00197 <TYP, L> 00198 00199 # define BIND_FRIEND_OPERATOR_PART_2B(TYP1,L,TYP2)\ 00200 <TYP1, L, TYP2> 00201 00202 # endif 00203 00204 /* XXX 00205 * The gcc-3.x object model has changes which allow THIS to change 00206 * based upon inheritance and such. That isn't a problem. However, 00207 * they added a poor warning which breaks ANY use of offsetof(), even 00208 * legitimate cases where it is THE ONLY way to get the correct result and 00209 * where the result would be correct with the new model. This offsetof 00210 * implementation is designed to avoid that particular compiler warning. 00211 * Until the GCC guys admit they are doing something dumb, we need to do this. 00212 * 00213 * This could arguably belong in w_base.h, I put it here since w_base.h 00214 * always sucks this in and it is a compiler-dependency. 00215 */ 00216 #if W_GCC_THIS_VER >= W_GCC_VER(3,0) 00217 #define w_offsetof(t,f) \ 00218 ((size_t)((char*)&(*(t*)sizeof(t)).f - (char *)&(*(t*)sizeof(t)))) 00219 #endif 00220 00221 #endif /* __GNUC__ */ 00222 00223 #ifdef __SUNPRO_CC 00224 # define BIND_FRIEND_OPERATOR_PART_1(TYP,L,TMPLa,TMPLb) \ 00225 template <class TYP, class L> \ 00226 ostream & operator<<(ostream&o, const TMPLa,TMPLb& l); 00227 00228 # define BIND_FRIEND_OPERATOR_PART_1B(TYP1,TYP3, TYP2,TMPLa,TMPLc,TMPLb) \ 00229 template <class TYP1, class TYP3, class TYP2> \ 00230 ostream & operator<<(ostream&o, const TMPLa,TMPLc,TMPLb& l); 00231 00232 # define BIND_FRIEND_OPERATOR_PART_2(TYP,L)\ 00233 <TYP,L> 00234 00235 # define BIND_FRIEND_OPERATOR_PART_2B(TYP1,L,TYP2)\ 00236 <TYP1,L,TYP2> 00237 #endif 00238 /****************************************************************************** 00239 * 00240 * gcc complains about big literals which don't have the LL suffix. 00241 * don't know if egcs or gcc 2.95 have this problem, but it shouldn't hurt. 00242 * 00243 ******************************************************************************/ 00244 #ifdef __GNUC__ 00245 #define INT64_LITERAL_BUG(x) x ## LL 00246 #else 00247 #define INT64_LITERAL_BUG(x) x 00248 #endif 00249 00250 /* There is a newer version of the STL out there, which is standard with 00251 gcc-2.95. It requires different template instantiations, but most 00252 other use of it is seamless from before. Specifiying the newer STL 00253 can either be enabled explicitly in shore.def, or automgically here 00254 for the appropriate gcc versions. XXX probably needs an updated 00255 expression if gcc changes major numbers again. */ 00256 #if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ > 90 00257 #define W_NEWER_STL 00258 #endif 00259 00260 /****************************************************************************** 00261 * 00262 * C string bug 00263 * 00264 ******************************************************************************/ 00265 00266 /* 00267 * a C string constant is of type (const char*). some routines assume that 00268 * they are (char*). this is to cast away the const in those cases. 00269 */ 00270 #define C_STRING_BUG (char *) 00271 00272 00273 /****************************************************************************** 00274 * 00275 * Perl library bugs 00276 * 00277 ******************************************************************************/ 00278 00279 /* 00280 * perl doesn't use const char* anywhere, and "string" is a const char*. 00281 */ 00282 #define PERL_CVBUG (char *) 00283 00284 /* 00285 * perl creates variable through macro expansions which aren't always used. 00286 */ 00287 #define PERL_UNUSED_VAR(x) (void)x 00288 00289 00290 /****************************************************************************** 00291 * 00292 * HP CC bugs 00293 * 00294 ******************************************************************************/ 00295 #if defined(Snake) && !defined(__GNUC__) 00296 00297 /* 00298 * HP CC does not like some enums with the high order bit set. 00299 */ 00300 # define HP_CC_BUG_1 1 00301 00302 /* 00303 * HP CC does not implement labels within blocks with destructors 00304 */ 00305 # define HP_CC_BUG_2 1 00306 00307 /* 00308 * HP CC does not support having a nested class as as a 00309 * parameter type to a template class 00310 */ 00311 # define HP_CC_BUG_3 1 00312 00313 #endif /* defined(Snake) && !defined(__GNUC__) */ 00314 00315 00316 /* This is really a library problem; stream.form() and stream.scan() 00317 aren't standard, but GNUisms. On the other hand, they should 00318 be in the standard, because they save us from static form() buffers. 00319 Using the W_FORM() and W_FORM2() macros instead of 00320 stream.form() or stream << form() encapsulates this use, so the 00321 optimal solution can be used on each platform. 00322 If a portable scan() equivalent is written, a similar set 00323 of W_SCAN macros could encapuslate input scanning too. 00324 */ 00325 #if defined(__GNUG__) 00326 #if W_GCC_THIS_VER < W_GCC_VER(3,0) 00327 #define FC_IOSTREAM_FORM_METHOD 00328 #else 00329 #define FC_NEED_UNBOUND_FORM 00330 #endif 00331 #elif defined(__SUNPRO_CC) 00332 #define FC_NEED_UNBOUND_FORM 00333 #endif 00334 00335 #ifdef FC_IOSTREAM_FORM_METHOD 00336 #define W_FORM(stream) stream . form 00337 #else 00338 #define W_FORM(stream) stream << form 00339 #endif 00340 00341 /* Grab our form if needed. */ 00342 #ifdef FC_NEED_UNBOUND_FORM 00343 // in w_form.cpp 00344 extern const char *form(const char *, ...); 00345 #endif 00346 00347 #define W_FORM2(stream,args) W_FORM(stream) args 00348 00349 /* 00350 * Default definitions of macros used everywhere: 00351 * NB: re: VC++/g++ differences in treatments of sizeof: 00352 * whereas sizeof(empty class) == 1 in both cases, 00353 * classes inheriting from an empty class don't get the 1 byte 00354 * added in by VC++, but in g++, those classes DO get an extra 1(4) 00355 * bytes(s) added in by the inheritance. 00356 */ 00357 #ifndef VCPP_BUG_1 00358 #define VCPP_BUG_1 00359 #endif 00360 00361 /* 00362 * Try to use the system definition of offsetof, and provide one here 00363 * if the system's isn't in the standard place. 00364 */ 00365 #ifndef offsetof 00366 #include <cstddef> 00367 #endif 00368 #ifndef offsetof 00369 #define offsetof(type,member) ((size_t)((&(type *)0)->member)) 00370 #endif 00371 00372 #ifndef w_offsetof 00373 /* FRJ: Sun's CC returns an address near the top of the stack when 00374 given ``offsetof(a, b.c())'', where c() returns a reference to a 00375 private member of b. This seems to work around the issue (bug?). 00376 OLD: 00377 //template<class T> 00378 //static T* get_null() { return NULL; } 00379 //#define w_offsetof(class,member) ((size_t) &get_null<class>()->member) 00380 NEW: below 00381 */ 00382 #define w_offsetof(class,member) offsetof(class,member) 00383 #endif 00384 00385 /*<std-footer incl-file-exclusion='W_WORKAROUND_H'> -- do not edit anything below this line -- */ 00386 00387 #endif /*</std-footer>*/