The assert macro prototype is defined in the header file assert. in h, it is used to terminate the execution of the program if the condition following the macro returns false. The macro will call the _ assert_fail function, which first outputs error information to stderr, then, call the abort function to terminate the program execution.
1. assert macro definition
As follows:
[Cpp]
# Define assert (expr )\
(Expr )\
? _ ASSERT_VOID_CAST (0 )\
: _ Assert_fail (_ STRING (expr), _ FILE __, _ LINE __, _ ASSERT_FUNCTION ))
The _ assert_fail function is a library export function, which is defined as follows:
[Cpp]
/* This prints an "Assertion failed" message and aborts .*/
Extern void _ assert_fail (_ const char * _ assertion, _ const char * _ file,
Unsigned int _ line, _ const char * _ function)
_ THROW _ attribute _ (_ noreturn __));
Note the above _ attribute _ (_ noreturn _) Definition. This attribute notifies the compiler that this function never returns. After this function program is run, it exits.
2. Disable assert macros
Pay attention to a macro. This macro is very useful. How can I disable assert Macros?
[Cpp]
# Ifdef NDEBUG
# Define assert (expr) (_ ASSERT_VOID_CAST (0 ))
/* Void assert_perror (int errnum );
If NDEBUG is defined, do nothing. If not, and ERRNUM is not zero, print
Error message with the error text for ERRNUM and abort.
(This is a GNU extension .)*/
# Ifdef _ USE_GNU
# Define assert_perror (errnum) (_ ASSERT_VOID_CAST (0 ))
# Endif
# Else/* Not NDEBUG .*/
Therefore, if we define the NDEBUG macro ourselves, assert will not work, because the _ ASSERT_VOID_CAST macro is defined as follows:
[Cpp]
# If defined _ cplusplus & _ GNUC_PREREQ (2,95)
# Define _ ASSERT_VOID_CAST static_cast <void>
# Else
# Define _ ASSERT_VOID_CAST (void)
# Endif
Iii. assert macro considerations
It is best to use the assert macro to check a condition, that is, do not use the & or | Operator. This makes it easier to find out which condition has a problem. When necessary, write several more assert macros.
Do not use assert for variable modification, such as assert (k ++> 10). Because we may disable this macro, k ++ will not execute at this time, as we can see above.
Assert is not a condition filter.
4. Customize ASSERT macros
We can define and implement ASSERT macros by ourselves, so that we can get more error messages and customize error behaviors.
[Cpp]
# Ifndef ASSERT
# Define ASSERT (x )\
(Void) Assert (x), _ FUNCTION __, _ FILE __, _ LINE __, # x)
# Endif
The Assert implementation is as follows:
[Cpp]
Inline bool Assert (bool result, const char * function, const char * file,
Int line, const char * expression ){
If (! Result ){
Log_Assert (function, file, line, expression );
Break ();
Return false;
}
Return true;
}
The above Log_Assert function is only used to output error messages.
Break defines the behavior of error handling. The function is defined as follows:
[Cpp]
Void Break (){
# If WIN32
: DebugBreak ();
# Elif OSX //! WIN32
: Debugger ();
# Else //! OSX &&! WIN32
# If _ DEBUG_HAVE_BACKTRACE
OutputTrace ();
# Endif
Abort ();
# Endif //! OSX &&! WIN32
}
DebugBreak is a VC library function that can append debugging information to processes and add breakpoints or something. In fact, we sometimes ask if we want to debug it, if we select Yes, a development environment will be started and the debugger will be opened.
It is best to enable the namespace when implementing ASSERT, which makes it easier to control this macro.