1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Misc debug functions and macros
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 1998-2009 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
14 #if !defined(__WXPALMOS5__) && !defined(__WXWINCE__)
16 #endif // systems without assert.h
18 #include <limits.h> // for CHAR_BIT used below
20 #include "wx/chartype.h" // for __TFILE__ and wxChar
21 #include "wx/cpp.h" // for __WXFUNCTION__
23 class WXDLLIMPEXP_FWD_BASE wxString
;
24 class WXDLLIMPEXP_FWD_BASE wxCStrData
;
26 // ----------------------------------------------------------------------------
27 // Defines controlling the debugging macros
28 // ----------------------------------------------------------------------------
31 wxWidgets can be built with several different levels of debug support
32 specified by the value of wxDEBUG_LEVEL constant:
34 0: No assertion macros at all, this should only be used when optimizing
35 for resource-constrained systems (typically embedded ones).
36 1: Default level, most of the assertions are enabled.
37 2: Maximal (at least for now): asserts which are "expensive"
38 (performance-wise) or only make sense for finding errors in wxWidgets
39 itself, as opposed to bugs in applications using it, are also enabled.
41 For compatibility reasons, currently wxDEBUG_LEVEL is defined if
42 __WXDEBUG__ is defined but in the near future (2.9.1) the role of the flags
43 will change and wxDEBUG_LEVEL will be the primary value with __WXDEBUG__
44 only used for compatibility.
47 // if _DEBUG is defined (MS VC++ and others use it in debug builds), define
52 #endif // !__WXDEBUG__
55 // if NDEBUG is defined (<assert.h> uses it), undef __WXDEBUG__ and WXDEBUG
61 // if __WXDEBUG__ is defined, make sure that WXDEBUG is defined and >= 1
63 #if !defined(WXDEBUG) || !WXDEBUG
69 // temporarily define wxDEBUG_LEVEL as function of __WXDEBUG__
70 #if !defined(wxDEBUG_LEVEL)
72 #define wxDEBUG_LEVEL 1
74 #define wxDEBUG_LEVEL 0
76 #endif // !defined(wxDEBUG_LEVEL)
78 // ----------------------------------------------------------------------------
79 // Handling assertion failures
80 // ----------------------------------------------------------------------------
83 Type for the function called in case of assert failure, see
86 typedef void (*wxAssertHandler_t
)(const wxString
& file
,
94 // the global assert handler function, if it is NULL asserts don't check their
96 extern WXDLLIMPEXP_DATA_BASE(wxAssertHandler_t
) wxTheAssertHandler
;
99 Sets the function to be called in case of assertion failure.
101 The default assert handler forwards to wxApp::OnAssertFailure() whose
102 default behaviour is, in turn, to show the standard assertion failure
103 dialog if a wxApp object exists or shows the same dialog itself directly
106 While usually it is enough -- and more convenient -- to just override
107 OnAssertFailure(), to handle all assertion failures, including those
108 occurring even before wxApp object creation or after its destruction you
109 need to provide your assertion handler function.
111 This function also provides a simple way to disable all asserts: simply
112 pass NULL pointer to it. Doing this will result in not even evaluating
113 assert conditions at all, avoiding almost all run-time cost of asserts.
115 Notice that this function is not MT-safe, so you should call it before
116 starting any other threads.
118 The return value of this function is the previous assertion handler. It can
119 be called after any pre-processing by your handler and can also be restored
120 later if you uninstall your handler.
122 inline wxAssertHandler_t
wxSetAssertHandler(wxAssertHandler_t handler
)
124 const wxAssertHandler_t old
= wxTheAssertHandler
;
125 wxTheAssertHandler
= handler
;
129 #else // !wxDEBUG_LEVEL
131 // provide empty stubs in case assertions are completely disabled
133 // NB: can't use WXUNUSED() here as we're included from wx/defs.h before it is
135 inline wxAssertHandler_t
wxSetAssertHandler(wxAssertHandler_t
/* handler */)
140 #endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL
142 // simply a synonym for wxSetAssertHandler(NULL)
143 inline void wxDisableAsserts() { wxSetAssertHandler(NULL
); }
148 wxOnAssert() is used by the debugging macros defined below. Different
149 overloads are needed because these macros can be used with or without _T().
151 All of them are implemented in src/common/appcmn.cpp and unconditionally
152 call wxTheAssertHandler so the caller must check that it is non-NULL
153 (assert macros do it).
158 // these overloads are the ones typically used by debugging macros: we have to
159 // provide wxChar* msg version because it's common to use _T() in the macros
160 // and finally, we can't use const wx(char)* msg = NULL, because that would
163 // also notice that these functions can't be inline as wxString is not defined
164 // yet (and can't be as wxString code itself may use assertions)
165 extern void WXDLLIMPEXP_BASE
wxOnAssert(const char *file
,
170 extern void WXDLLIMPEXP_BASE
wxOnAssert(const char *file
,
176 extern void WXDLLIMPEXP_BASE
wxOnAssert(const char *file
,
181 #endif /* wxUSE_UNICODE */
183 // this version is for compatibility with wx 2.8 Unicode build only, we don't
184 // use it ourselves any more except in ANSI-only build in which case it is all
186 extern void WXDLLIMPEXP_BASE
wxOnAssert(const wxChar
*file
,
190 const wxChar
*msg
= NULL
);
192 // these overloads work when msg passed to debug macro is a string and we
193 // also have to provide wxCStrData overload to resolve ambiguity which would
194 // otherwise arise from wxASSERT( s.c_str() )
195 extern void WXDLLIMPEXP_BASE
wxOnAssert(const wxString
& file
,
197 const wxString
& func
,
198 const wxString
& cond
,
199 const wxString
& msg
);
201 extern void WXDLLIMPEXP_BASE
wxOnAssert(const wxString
& file
,
203 const wxString
& func
,
204 const wxString
& cond
);
206 extern void WXDLLIMPEXP_BASE
wxOnAssert(const char *file
,
210 const wxCStrData
& msg
);
212 extern void WXDLLIMPEXP_BASE
wxOnAssert(const char *file
,
216 const wxString
& msg
);
218 #endif // wxDEBUG_LEVEL
221 // ----------------------------------------------------------------------------
223 // ----------------------------------------------------------------------------
226 Assertion macros: check if the condition is true and call assert handler
227 (which will by default notify the user about failure) if it isn't.
229 wxASSERT and wxFAIL macros as well as wxTrap() function do nothing at all
230 if wxDEBUG_LEVEL is 0 however they do check their conditions at default
231 debug level 1, unlike the previous wxWidgets versions.
233 wxASSERT_LEVEL_2 is meant to be used for "expensive" asserts which should
234 normally be disabled because they have a big impact on performance and so
235 this macro only does anything if wxDEBUG_LEVEL >= 2.
238 // call this function to break into the debugger unconditionally (assuming
239 // the program is running under debugger, of course)
240 extern void WXDLLIMPEXP_BASE
wxTrap();
242 // assert checks if the condition is true and calls the assert handler with
243 // the provided message if it isn't
245 // NB: the macro is defined like this to ensure that nested if/else
246 // statements containing it are compiled in the same way whether it is
247 // defined as empty or not; also notice that we can't use ";" instead
248 // of "{}" as some compilers warn about "possible unwanted ;" then
249 #define wxASSERT_MSG(cond, msg) \
250 if ( !wxTheAssertHandler || (cond) ) \
253 wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, #cond, msg)
255 // a version without any additional message, don't use unless condition
256 // itself is fully self-explanatory
257 #define wxASSERT(cond) wxASSERT_MSG(cond, (const char*)NULL)
259 // wxFAIL is a special form of assert: it always triggers (and so is
260 // usually used in normally unreachable code)
261 #define wxFAIL_COND_MSG(cond, msg) \
262 wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, cond, msg)
263 #define wxFAIL_MSG(msg) wxFAIL_COND_MSG("Assert failure", msg)
264 #define wxFAIL wxFAIL_MSG((const char*)NULL)
265 #else // !wxDEBUG_LEVEL
268 #define wxASSERT(cond)
269 #define wxASSERT_MSG(cond, msg)
271 #define wxFAIL_MSG(msg)
272 #define wxFAIL_COND_MSG(cond, msg)
273 #endif // wxDEBUG_LEVEL
275 #if wxDEBUG_LEVEL >= 2
276 #define wxASSERT_LEVEL_2_MSG(cond, msg) wxASSERT_MSG(cond, msg)
277 #define wxASSERT_LEVEL_2(cond) wxASSERT(cond)
278 #else // wxDEBUG_LEVEL < 2
279 #define wxASSERT_LEVEL_2_MSG(cond, msg)
280 #define wxASSERT_LEVEL_2(cond)
285 wxCHECK macros always check their conditions, setting debug level to 0 only
286 makes them silent in case of failure, otherwise -- including at default
287 debug level 1 -- they call the assert handler if the condition is false
289 They are supposed to be used only in invalid situation: for example, an
290 invalid parameter (e.g. a NULL pointer) is passed to a function. Instead of
291 dereferencing it and causing core dump the function might use
293 wxCHECK_RET( p != NULL, "pointer can't be NULL" )
296 // the generic macro: takes the condition to check, the statement to be execute
297 // in case the condition is false and the message to pass to the assert handler
298 #define wxCHECK2_MSG(cond, op, msg) \
303 wxFAIL_COND_MSG(#cond, msg); \
306 struct wxDummyCheckStruct /* just to force a semicolon */
308 // check which returns with the specified return code if the condition fails
309 #define wxCHECK_MSG(cond, rc, msg) wxCHECK2_MSG(cond, return rc, msg)
311 // check that expression is true, "return" if not (also FAILs in debug mode)
312 #define wxCHECK(cond, rc) wxCHECK_MSG(cond, rc, (const char*)NULL)
314 // check that expression is true, perform op if not
315 #define wxCHECK2(cond, op) wxCHECK2_MSG(cond, op, (const char*)NULL)
317 // special form of wxCHECK2: as wxCHECK, but for use in void functions
319 // NB: there is only one form (with msg parameter) and it's intentional:
320 // there is no other way to tell the caller what exactly went wrong
321 // from the void function (of course, the function shouldn't be void
323 #define wxCHECK_RET(cond, msg) wxCHECK2_MSG(cond, return, msg)
326 // ----------------------------------------------------------------------------
327 // Compile time asserts
329 // Unlike the normal assert and related macros above which are checked during
330 // the program run-time the macros below will result in a compilation error if
331 // the condition they check is false. This is usually used to check the
332 // expressions containing sizeof()s which cannot be tested with the
333 // preprocessor. If you can use the #if's, do use them as you can give a more
334 // detailed error message then.
335 // ----------------------------------------------------------------------------
338 How this works (you don't have to understand it to be able to use the
339 macros): we rely on the fact that it is invalid to define a named bit field
340 in a struct of width 0. All the rest are just the hacks to minimize the
341 possibility of the compiler warnings when compiling this macro: in
342 particular, this is why we define a struct and not an object (which would
343 result in a warning about unused variable) and a named struct (otherwise we'd
344 get a warning about an unnamed struct not used to define an object!).
347 #define wxMAKE_UNIQUE_ASSERT_NAME wxMAKE_UNIQUE_NAME(wxAssert_)
350 The second argument of this macro must be a valid C++ identifier and not a
351 string. I.e. you should use it like this:
353 wxCOMPILE_TIME_ASSERT( sizeof(int) >= 2, YourIntsAreTooSmall );
355 It may be used both within a function and in the global scope.
357 #if defined(__WATCOMC__)
358 /* avoid "unused symbol" warning */
359 #define wxCOMPILE_TIME_ASSERT(expr, msg) \
360 class wxMAKE_UNIQUE_ASSERT_NAME { \
361 unsigned int msg: expr; \
362 wxMAKE_UNIQUE_ASSERT_NAME() { wxUnusedVar(msg); } \
365 #define wxCOMPILE_TIME_ASSERT(expr, msg) \
366 struct wxMAKE_UNIQUE_ASSERT_NAME { unsigned int msg: expr; }
370 When using VC++ 6 with "Edit and Continue" on, the compiler completely
371 mishandles __LINE__ and so wxCOMPILE_TIME_ASSERT() doesn't work, provide a
372 way to make "unique" assert names by specifying a unique prefix explicitly
374 #define wxMAKE_UNIQUE_ASSERT_NAME2(text) wxCONCAT(wxAssert_, text)
376 #define wxCOMPILE_TIME_ASSERT2(expr, msg, text) \
377 struct wxMAKE_UNIQUE_ASSERT_NAME2(text) { unsigned int msg: expr; }
379 // helpers for wxCOMPILE_TIME_ASSERT below, for private use only
380 #define wxMAKE_BITSIZE_MSG(type, size) type ## SmallerThan ## size ## Bits
382 // a special case of compile time assert: check that the size of the given type
383 // is at least the given number of bits
384 #define wxASSERT_MIN_BITSIZE(type, size) \
385 wxCOMPILE_TIME_ASSERT(sizeof(type) * CHAR_BIT >= size, \
386 wxMAKE_BITSIZE_MSG(type, size))
389 // ----------------------------------------------------------------------------
390 // other miscellaneous debugger-related functions
391 // ----------------------------------------------------------------------------
394 Return true if we're running under debugger.
396 Currently this only really works under Win32 and Mac in CodeWarrior builds,
397 it always returns false in other cases.
399 #if defined(__WXMAC__) || defined(__WIN32__)
400 extern bool WXDLLIMPEXP_BASE
wxIsDebuggerRunning();
402 inline bool wxIsDebuggerRunning() { return false; }
405 // An assert helper used to avoid warning when testing constant expressions,
406 // i.e. wxASSERT( sizeof(int) == 4 ) can generate a compiler warning about
407 // expression being always true, but not using
408 // wxASSERT( wxAssertIsEqual(sizeof(int), 4) )
410 // NB: this is made obsolete by wxCOMPILE_TIME_ASSERT() and should no
412 extern bool WXDLLIMPEXP_BASE
wxAssertIsEqual(int x
, int y
);
414 // Use of wxFalse instead of false suppresses compiler warnings about testing
415 // constant expression
416 extern WXDLLIMPEXP_DATA_BASE(const bool) wxFalse
;
418 #define wxAssertFailure wxFalse
420 // This is similar to WXUNUSED() and useful for parameters which are only used
423 #define WXUNUSED_UNLESS_DEBUG(param) param
425 #define WXUNUSED_UNLESS_DEBUG(param) WXUNUSED(param)
429 #endif // _WX_DEBUG_H_