| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: wx/debug.h |
| 3 | // Purpose: Misc debug functions and macros |
| 4 | // Author: Vadim Zeitlin |
| 5 | // Created: 29/01/98 |
| 6 | // RCS-ID: $Id$ |
| 7 | // Copyright: (c) 1998-2009 Vadim Zeitlin <vadim@wxwidgets.org> |
| 8 | // Licence: wxWindows licence |
| 9 | ///////////////////////////////////////////////////////////////////////////// |
| 10 | |
| 11 | #ifndef _WX_DEBUG_H_ |
| 12 | #define _WX_DEBUG_H_ |
| 13 | |
| 14 | #if !defined(__WXWINCE__) |
| 15 | #include <assert.h> |
| 16 | #endif // systems without assert.h |
| 17 | |
| 18 | #include <limits.h> // for CHAR_BIT used below |
| 19 | |
| 20 | #include "wx/chartype.h" // for __TFILE__ and wxChar |
| 21 | #include "wx/cpp.h" // for __WXFUNCTION__ |
| 22 | #include "wx/dlimpexp.h" // for WXDLLIMPEXP_FWD_BASE |
| 23 | |
| 24 | class WXDLLIMPEXP_FWD_BASE wxString; |
| 25 | class WXDLLIMPEXP_FWD_BASE wxCStrData; |
| 26 | |
| 27 | // ---------------------------------------------------------------------------- |
| 28 | // Defines controlling the debugging macros |
| 29 | // ---------------------------------------------------------------------------- |
| 30 | |
| 31 | /* |
| 32 | wxWidgets can be built with several different levels of debug support |
| 33 | specified by the value of wxDEBUG_LEVEL constant: |
| 34 | |
| 35 | 0: No assertion macros at all, this should only be used when optimizing |
| 36 | for resource-constrained systems (typically embedded ones). |
| 37 | 1: Default level, most of the assertions are enabled. |
| 38 | 2: Maximal (at least for now): asserts which are "expensive" |
| 39 | (performance-wise) or only make sense for finding errors in wxWidgets |
| 40 | itself, as opposed to bugs in applications using it, are also enabled. |
| 41 | */ |
| 42 | |
| 43 | // unless wxDEBUG_LEVEL is predefined (by configure or via wx/setup.h under |
| 44 | // Windows), use the default |
| 45 | #if !defined(wxDEBUG_LEVEL) |
| 46 | #define wxDEBUG_LEVEL 1 |
| 47 | #endif // !defined(wxDEBUG_LEVEL) |
| 48 | |
| 49 | /* |
| 50 | __WXDEBUG__ is defined when wxDEBUG_LEVEL != 0. This is done mostly for |
| 51 | compatibility but it also provides a simpler way to check if asserts and |
| 52 | debug logging is enabled at all. |
| 53 | */ |
| 54 | #if wxDEBUG_LEVEL > 0 |
| 55 | #ifndef __WXDEBUG__ |
| 56 | #define __WXDEBUG__ |
| 57 | #endif |
| 58 | #else |
| 59 | #undef __WXDEBUG__ |
| 60 | #endif |
| 61 | |
| 62 | // Finally there is also a very old WXDEBUG macro not used anywhere at all, it |
| 63 | // is only defined for compatibility. |
| 64 | #ifdef __WXDEBUG__ |
| 65 | #if !defined(WXDEBUG) || !WXDEBUG |
| 66 | #undef WXDEBUG |
| 67 | #define WXDEBUG 1 |
| 68 | #endif // !WXDEBUG |
| 69 | #endif // __WXDEBUG__ |
| 70 | |
| 71 | // ---------------------------------------------------------------------------- |
| 72 | // Handling assertion failures |
| 73 | // ---------------------------------------------------------------------------- |
| 74 | |
| 75 | /* |
| 76 | Type for the function called in case of assert failure, see |
| 77 | wxSetAssertHandler(). |
| 78 | */ |
| 79 | typedef void (*wxAssertHandler_t)(const wxString& file, |
| 80 | int line, |
| 81 | const wxString& func, |
| 82 | const wxString& cond, |
| 83 | const wxString& msg); |
| 84 | |
| 85 | #if wxDEBUG_LEVEL |
| 86 | |
| 87 | // the global assert handler function, if it is NULL asserts don't check their |
| 88 | // conditions |
| 89 | extern WXDLLIMPEXP_DATA_BASE(wxAssertHandler_t) wxTheAssertHandler; |
| 90 | |
| 91 | /* |
| 92 | Sets the function to be called in case of assertion failure. |
| 93 | |
| 94 | The default assert handler forwards to wxApp::OnAssertFailure() whose |
| 95 | default behaviour is, in turn, to show the standard assertion failure |
| 96 | dialog if a wxApp object exists or shows the same dialog itself directly |
| 97 | otherwise. |
| 98 | |
| 99 | While usually it is enough -- and more convenient -- to just override |
| 100 | OnAssertFailure(), to handle all assertion failures, including those |
| 101 | occurring even before wxApp object creation or after its destruction you |
| 102 | need to provide your assertion handler function. |
| 103 | |
| 104 | This function also provides a simple way to disable all asserts: simply |
| 105 | pass NULL pointer to it. Doing this will result in not even evaluating |
| 106 | assert conditions at all, avoiding almost all run-time cost of asserts. |
| 107 | |
| 108 | Notice that this function is not MT-safe, so you should call it before |
| 109 | starting any other threads. |
| 110 | |
| 111 | The return value of this function is the previous assertion handler. It can |
| 112 | be called after any pre-processing by your handler and can also be restored |
| 113 | later if you uninstall your handler. |
| 114 | */ |
| 115 | inline wxAssertHandler_t wxSetAssertHandler(wxAssertHandler_t handler) |
| 116 | { |
| 117 | const wxAssertHandler_t old = wxTheAssertHandler; |
| 118 | wxTheAssertHandler = handler; |
| 119 | return old; |
| 120 | } |
| 121 | |
| 122 | /* |
| 123 | Reset the default assert handler. |
| 124 | |
| 125 | This may be used to enable asserts, which are disabled by default in this |
| 126 | case, for programs built in release build (NDEBUG defined). |
| 127 | */ |
| 128 | extern void WXDLLIMPEXP_BASE wxSetDefaultAssertHandler(); |
| 129 | |
| 130 | #else // !wxDEBUG_LEVEL |
| 131 | |
| 132 | // provide empty stubs in case assertions are completely disabled |
| 133 | // |
| 134 | // NB: can't use WXUNUSED() here as we're included from wx/defs.h before it is |
| 135 | // defined |
| 136 | inline wxAssertHandler_t wxSetAssertHandler(wxAssertHandler_t /* handler */) |
| 137 | { |
| 138 | return NULL; |
| 139 | } |
| 140 | |
| 141 | inline void wxSetDefaultAssertHandler() { } |
| 142 | |
| 143 | #endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL |
| 144 | |
| 145 | // simply a synonym for wxSetAssertHandler(NULL) |
| 146 | inline void wxDisableAsserts() { wxSetAssertHandler(NULL); } |
| 147 | |
| 148 | /* |
| 149 | A macro which disables asserts for applications compiled in release build. |
| 150 | |
| 151 | By default, wxIMPLEMENT_APP (or rather wxIMPLEMENT_WXWIN_MAIN) disable the |
| 152 | asserts in the applications compiled in the release build by calling this. |
| 153 | It does nothing if NDEBUG is not defined. |
| 154 | */ |
| 155 | #ifdef NDEBUG |
| 156 | #define wxDISABLE_ASSERTS_IN_RELEASE_BUILD() wxDisableAsserts() |
| 157 | #else |
| 158 | #define wxDISABLE_ASSERTS_IN_RELEASE_BUILD() |
| 159 | #endif |
| 160 | |
| 161 | #if wxDEBUG_LEVEL |
| 162 | |
| 163 | /* |
| 164 | wxOnAssert() is used by the debugging macros defined below. Different |
| 165 | overloads are needed because these macros can be used with or without wxT(). |
| 166 | |
| 167 | All of them are implemented in src/common/appcmn.cpp and unconditionally |
| 168 | call wxTheAssertHandler so the caller must check that it is non-NULL |
| 169 | (assert macros do it). |
| 170 | */ |
| 171 | |
| 172 | #if wxUSE_UNICODE |
| 173 | |
| 174 | // these overloads are the ones typically used by debugging macros: we have to |
| 175 | // provide wxChar* msg version because it's common to use wxT() in the macros |
| 176 | // and finally, we can't use const wx(char)* msg = NULL, because that would |
| 177 | // be ambiguous |
| 178 | // |
| 179 | // also notice that these functions can't be inline as wxString is not defined |
| 180 | // yet (and can't be as wxString code itself may use assertions) |
| 181 | extern WXDLLIMPEXP_BASE void wxOnAssert(const char *file, |
| 182 | int line, |
| 183 | const char *func, |
| 184 | const char *cond); |
| 185 | |
| 186 | extern WXDLLIMPEXP_BASE void wxOnAssert(const char *file, |
| 187 | int line, |
| 188 | const char *func, |
| 189 | const char *cond, |
| 190 | const char *msg); |
| 191 | |
| 192 | extern WXDLLIMPEXP_BASE void wxOnAssert(const char *file, |
| 193 | int line, |
| 194 | const char *func, |
| 195 | const char *cond, |
| 196 | const wxChar *msg) ; |
| 197 | #endif /* wxUSE_UNICODE */ |
| 198 | |
| 199 | // this version is for compatibility with wx 2.8 Unicode build only, we don't |
| 200 | // use it ourselves any more except in ANSI-only build in which case it is all |
| 201 | // we need |
| 202 | extern WXDLLIMPEXP_BASE void wxOnAssert(const wxChar *file, |
| 203 | int line, |
| 204 | const char *func, |
| 205 | const wxChar *cond, |
| 206 | const wxChar *msg = NULL); |
| 207 | |
| 208 | // these overloads work when msg passed to debug macro is a string and we |
| 209 | // also have to provide wxCStrData overload to resolve ambiguity which would |
| 210 | // otherwise arise from wxASSERT( s.c_str() ) |
| 211 | extern WXDLLIMPEXP_BASE void wxOnAssert(const wxString& file, |
| 212 | int line, |
| 213 | const wxString& func, |
| 214 | const wxString& cond, |
| 215 | const wxString& msg); |
| 216 | |
| 217 | extern WXDLLIMPEXP_BASE void wxOnAssert(const wxString& file, |
| 218 | int line, |
| 219 | const wxString& func, |
| 220 | const wxString& cond); |
| 221 | |
| 222 | extern WXDLLIMPEXP_BASE void wxOnAssert(const char *file, |
| 223 | int line, |
| 224 | const char *func, |
| 225 | const char *cond, |
| 226 | const wxCStrData& msg); |
| 227 | |
| 228 | extern WXDLLIMPEXP_BASE void wxOnAssert(const char *file, |
| 229 | int line, |
| 230 | const char *func, |
| 231 | const char *cond, |
| 232 | const wxString& msg); |
| 233 | |
| 234 | #endif // wxDEBUG_LEVEL |
| 235 | |
| 236 | |
| 237 | // ---------------------------------------------------------------------------- |
| 238 | // Debugging macros |
| 239 | // ---------------------------------------------------------------------------- |
| 240 | |
| 241 | /* |
| 242 | Assertion macros: check if the condition is true and call assert handler |
| 243 | (which will by default notify the user about failure) if it isn't. |
| 244 | |
| 245 | wxASSERT and wxFAIL macros as well as wxTrap() function do nothing at all |
| 246 | if wxDEBUG_LEVEL is 0 however they do check their conditions at default |
| 247 | debug level 1, unlike the previous wxWidgets versions. |
| 248 | |
| 249 | wxASSERT_LEVEL_2 is meant to be used for "expensive" asserts which should |
| 250 | normally be disabled because they have a big impact on performance and so |
| 251 | this macro only does anything if wxDEBUG_LEVEL >= 2. |
| 252 | */ |
| 253 | #if wxDEBUG_LEVEL |
| 254 | // wxTrap() can be used to break into the debugger unconditionally |
| 255 | // (assuming the program is running under debugger, of course). |
| 256 | // |
| 257 | // If possible, we prefer to define it as a macro rather than as a function |
| 258 | // to open the debugger at the position where we trapped and not inside the |
| 259 | // trap function itself which is not very useful. |
| 260 | #if wxCHECK_VISUALC_VERSION(7) |
| 261 | #define wxTrap() __debugbreak() |
| 262 | #else |
| 263 | extern WXDLLIMPEXP_BASE void wxTrap(); |
| 264 | #endif // Win VisualC |
| 265 | |
| 266 | // Global flag used to indicate that assert macros should call wxTrap(): it |
| 267 | // is set by the default assert handler if the user answers yes to the |
| 268 | // question of whether to trap. |
| 269 | extern WXDLLIMPEXP_DATA_BASE(bool) wxTrapInAssert; |
| 270 | |
| 271 | // This macro checks if the condition is true and calls the assert handler |
| 272 | // with the provided message if it isn't and finally traps if the special |
| 273 | // flag indicating that it should do it was set by the handler. |
| 274 | // |
| 275 | // Notice that we don't use the handler return value for compatibility |
| 276 | // reasons (if we changed its return type, we'd need to change wxApp:: |
| 277 | // OnAssertFailure() too which would break user code overriding it), hence |
| 278 | // the need for the ugly global flag. |
| 279 | #define wxASSERT_MSG(cond, msg) \ |
| 280 | wxSTATEMENT_MACRO_BEGIN \ |
| 281 | if ( wxTheAssertHandler && !(cond) && \ |
| 282 | (wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, \ |
| 283 | #cond, msg), wxTrapInAssert) ) \ |
| 284 | { \ |
| 285 | wxTrapInAssert = false; \ |
| 286 | wxTrap(); \ |
| 287 | } \ |
| 288 | wxSTATEMENT_MACRO_END |
| 289 | |
| 290 | // a version without any additional message, don't use unless condition |
| 291 | // itself is fully self-explanatory |
| 292 | #define wxASSERT(cond) wxASSERT_MSG(cond, (const char*)NULL) |
| 293 | |
| 294 | // wxFAIL is a special form of assert: it always triggers (and so is |
| 295 | // usually used in normally unreachable code) |
| 296 | #define wxFAIL_COND_MSG(cond, msg) \ |
| 297 | wxSTATEMENT_MACRO_BEGIN \ |
| 298 | if ( wxTheAssertHandler && \ |
| 299 | (wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, \ |
| 300 | cond, msg), wxTrapInAssert) ) \ |
| 301 | { \ |
| 302 | wxTrapInAssert = false; \ |
| 303 | wxTrap(); \ |
| 304 | } \ |
| 305 | wxSTATEMENT_MACRO_END |
| 306 | |
| 307 | #define wxFAIL_MSG(msg) wxFAIL_COND_MSG("Assert failure", msg) |
| 308 | #define wxFAIL wxFAIL_MSG((const char*)NULL) |
| 309 | #else // !wxDEBUG_LEVEL |
| 310 | #define wxTrap() |
| 311 | |
| 312 | #define wxASSERT(cond) |
| 313 | #define wxASSERT_MSG(cond, msg) |
| 314 | #define wxFAIL |
| 315 | #define wxFAIL_MSG(msg) |
| 316 | #define wxFAIL_COND_MSG(cond, msg) |
| 317 | #endif // wxDEBUG_LEVEL |
| 318 | |
| 319 | #if wxDEBUG_LEVEL >= 2 |
| 320 | #define wxASSERT_LEVEL_2_MSG(cond, msg) wxASSERT_MSG(cond, msg) |
| 321 | #define wxASSERT_LEVEL_2(cond) wxASSERT(cond) |
| 322 | #else // wxDEBUG_LEVEL < 2 |
| 323 | #define wxASSERT_LEVEL_2_MSG(cond, msg) |
| 324 | #define wxASSERT_LEVEL_2(cond) |
| 325 | #endif |
| 326 | |
| 327 | // This is simply a wrapper for the standard abort() which is not available |
| 328 | // under all platforms. |
| 329 | // |
| 330 | // It isn't really debug-related but there doesn't seem to be any better place |
| 331 | // for it, so declare it here and define it in appbase.cpp, together with |
| 332 | // wxTrap(). |
| 333 | extern void WXDLLIMPEXP_BASE wxAbort(); |
| 334 | |
| 335 | /* |
| 336 | wxCHECK macros always check their conditions, setting debug level to 0 only |
| 337 | makes them silent in case of failure, otherwise -- including at default |
| 338 | debug level 1 -- they call the assert handler if the condition is false |
| 339 | |
| 340 | They are supposed to be used only in invalid situation: for example, an |
| 341 | invalid parameter (e.g. a NULL pointer) is passed to a function. Instead of |
| 342 | dereferencing it and causing core dump the function might use |
| 343 | |
| 344 | wxCHECK_RET( p != NULL, "pointer can't be NULL" ) |
| 345 | */ |
| 346 | |
| 347 | // the generic macro: takes the condition to check, the statement to be executed |
| 348 | // in case the condition is false and the message to pass to the assert handler |
| 349 | #define wxCHECK2_MSG(cond, op, msg) \ |
| 350 | if ( cond ) \ |
| 351 | {} \ |
| 352 | else \ |
| 353 | { \ |
| 354 | wxFAIL_COND_MSG(#cond, msg); \ |
| 355 | op; \ |
| 356 | } \ |
| 357 | struct wxDummyCheckStruct /* just to force a semicolon */ |
| 358 | |
| 359 | // check which returns with the specified return code if the condition fails |
| 360 | #define wxCHECK_MSG(cond, rc, msg) wxCHECK2_MSG(cond, return rc, msg) |
| 361 | |
| 362 | // check that expression is true, "return" if not (also FAILs in debug mode) |
| 363 | #define wxCHECK(cond, rc) wxCHECK_MSG(cond, rc, (const char*)NULL) |
| 364 | |
| 365 | // check that expression is true, perform op if not |
| 366 | #define wxCHECK2(cond, op) wxCHECK2_MSG(cond, op, (const char*)NULL) |
| 367 | |
| 368 | // special form of wxCHECK2: as wxCHECK, but for use in void functions |
| 369 | // |
| 370 | // NB: there is only one form (with msg parameter) and it's intentional: |
| 371 | // there is no other way to tell the caller what exactly went wrong |
| 372 | // from the void function (of course, the function shouldn't be void |
| 373 | // to begin with...) |
| 374 | #define wxCHECK_RET(cond, msg) wxCHECK2_MSG(cond, return, msg) |
| 375 | |
| 376 | |
| 377 | // ---------------------------------------------------------------------------- |
| 378 | // Compile time asserts |
| 379 | // |
| 380 | // Unlike the normal assert and related macros above which are checked during |
| 381 | // the program run-time the macros below will result in a compilation error if |
| 382 | // the condition they check is false. This is usually used to check the |
| 383 | // expressions containing sizeof()s which cannot be tested with the |
| 384 | // preprocessor. If you can use the #if's, do use them as you can give a more |
| 385 | // detailed error message then. |
| 386 | // ---------------------------------------------------------------------------- |
| 387 | |
| 388 | /* |
| 389 | How this works (you don't have to understand it to be able to use the |
| 390 | macros): we rely on the fact that it is invalid to define a named bit field |
| 391 | in a struct of width 0. All the rest are just the hacks to minimize the |
| 392 | possibility of the compiler warnings when compiling this macro: in |
| 393 | particular, this is why we define a struct and not an object (which would |
| 394 | result in a warning about unused variable) and a named struct (otherwise we'd |
| 395 | get a warning about an unnamed struct not used to define an object!). |
| 396 | */ |
| 397 | |
| 398 | #define wxMAKE_UNIQUE_ASSERT_NAME wxMAKE_UNIQUE_NAME(wxAssert_) |
| 399 | |
| 400 | /* |
| 401 | The second argument of this macro must be a valid C++ identifier and not a |
| 402 | string. I.e. you should use it like this: |
| 403 | |
| 404 | wxCOMPILE_TIME_ASSERT( sizeof(int) >= 2, YourIntsAreTooSmall ); |
| 405 | |
| 406 | It may be used both within a function and in the global scope. |
| 407 | */ |
| 408 | #if defined(__WATCOMC__) |
| 409 | /* avoid "unused symbol" warning */ |
| 410 | #define wxCOMPILE_TIME_ASSERT(expr, msg) \ |
| 411 | class wxMAKE_UNIQUE_ASSERT_NAME { \ |
| 412 | unsigned int msg: expr; \ |
| 413 | wxMAKE_UNIQUE_ASSERT_NAME() { wxUnusedVar(msg); } \ |
| 414 | } |
| 415 | #elif defined( __VMS ) |
| 416 | namespace wxdebug{ |
| 417 | |
| 418 | // HP aCC cannot deal with missing names for template value parameters |
| 419 | template <bool x> struct STATIC_ASSERTION_FAILURE; |
| 420 | |
| 421 | template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; |
| 422 | |
| 423 | // HP aCC cannot deal with missing names for template value parameters |
| 424 | template<int x> struct static_assert_test{}; |
| 425 | |
| 426 | } |
| 427 | #define WX_JOIN( X, Y ) X##Y |
| 428 | #define WX_STATIC_ASSERT_BOOL_CAST(x) (bool)(x) |
| 429 | #define wxCOMPILE_TIME_ASSERT(expr, msg) \ |
| 430 | typedef ::wxdebug::static_assert_test<\ |
| 431 | sizeof(::wxdebug::STATIC_ASSERTION_FAILURE< WX_STATIC_ASSERT_BOOL_CAST( expr ) >)>\ |
| 432 | WX_JOIN(wx_static_assert_typedef_, __LINE__) |
| 433 | #else |
| 434 | #define wxCOMPILE_TIME_ASSERT(expr, msg) \ |
| 435 | struct wxMAKE_UNIQUE_ASSERT_NAME { unsigned int msg: expr; } |
| 436 | #endif |
| 437 | |
| 438 | /* |
| 439 | When using VC++ 6 with "Edit and Continue" on, the compiler completely |
| 440 | mishandles __LINE__ and so wxCOMPILE_TIME_ASSERT() doesn't work, provide a |
| 441 | way to make "unique" assert names by specifying a unique prefix explicitly |
| 442 | */ |
| 443 | #define wxMAKE_UNIQUE_ASSERT_NAME2(text) wxCONCAT(wxAssert_, text) |
| 444 | |
| 445 | #define wxCOMPILE_TIME_ASSERT2(expr, msg, text) \ |
| 446 | struct wxMAKE_UNIQUE_ASSERT_NAME2(text) { unsigned int msg: expr; } |
| 447 | |
| 448 | // helpers for wxCOMPILE_TIME_ASSERT below, for private use only |
| 449 | #define wxMAKE_BITSIZE_MSG(type, size) type ## SmallerThan ## size ## Bits |
| 450 | |
| 451 | // a special case of compile time assert: check that the size of the given type |
| 452 | // is at least the given number of bits |
| 453 | #define wxASSERT_MIN_BITSIZE(type, size) \ |
| 454 | wxCOMPILE_TIME_ASSERT(sizeof(type) * CHAR_BIT >= size, \ |
| 455 | wxMAKE_BITSIZE_MSG(type, size)) |
| 456 | |
| 457 | |
| 458 | // ---------------------------------------------------------------------------- |
| 459 | // other miscellaneous debugger-related functions |
| 460 | // ---------------------------------------------------------------------------- |
| 461 | |
| 462 | /* |
| 463 | Return true if we're running under debugger. |
| 464 | |
| 465 | Currently only really works under Win32 and just returns false elsewhere. |
| 466 | */ |
| 467 | #if defined(__WIN32__) |
| 468 | extern bool WXDLLIMPEXP_BASE wxIsDebuggerRunning(); |
| 469 | #else // !Mac |
| 470 | inline bool wxIsDebuggerRunning() { return false; } |
| 471 | #endif // Mac/!Mac |
| 472 | |
| 473 | // An assert helper used to avoid warning when testing constant expressions, |
| 474 | // i.e. wxASSERT( sizeof(int) == 4 ) can generate a compiler warning about |
| 475 | // expression being always true, but not using |
| 476 | // wxASSERT( wxAssertIsEqual(sizeof(int), 4) ) |
| 477 | // |
| 478 | // NB: this is made obsolete by wxCOMPILE_TIME_ASSERT() and should no |
| 479 | // longer be used. |
| 480 | extern bool WXDLLIMPEXP_BASE wxAssertIsEqual(int x, int y); |
| 481 | |
| 482 | // Use of wxFalse instead of false suppresses compiler warnings about testing |
| 483 | // constant expression |
| 484 | extern WXDLLIMPEXP_DATA_BASE(const bool) wxFalse; |
| 485 | |
| 486 | #define wxAssertFailure wxFalse |
| 487 | |
| 488 | // This is similar to WXUNUSED() and useful for parameters which are only used |
| 489 | // in assertions. |
| 490 | #if wxDEBUG_LEVEL |
| 491 | #define WXUNUSED_UNLESS_DEBUG(param) param |
| 492 | #else |
| 493 | #define WXUNUSED_UNLESS_DEBUG(param) WXUNUSED(param) |
| 494 | #endif |
| 495 | |
| 496 | |
| 497 | #endif // _WX_DEBUG_H_ |