Below is a relatively simple Win32 Implementation of trace and assert:
# Define assert (expr )/
Do {/
If (! (Expr )&&/
(1 = _ crtdbgreport (_ crt_assert, _ file __, _ line __, null, # expr )))/
_ ASM {INT 3 };/
} While (0)
# Define trace (expr )/
_ Crtdbgreport (_ crt_warn, _ file __, _ line __, null, expr)
All of them call the _ crtdbgreport function. Its prototype is as follows:
_ Cribd int _ cdecl _ crtdbgreport (
Int nrpttype,
Const char * szfile,
Int nline,
Const char * szmodule,
Const char * szformat,
...
);
The first parameter of _ crtdbgreport indicates the type of the report message. There are three types:
# DEFINE _ crt_warn 0
# DEFINE _ crt_error 1
# DEFINE _ crt_assert 2
The implementation of the _ crtdbgreport function is to splice the report message first, and then send the message to the appropriate place based on the message type, as shown below:
First, judge the value of _ crtdbgmode [nrpttype ].
_ Crtdbgmode [0] = 2;
_ Crtdbgmode [1] = 4;
_ Crtdbgmode [2] = 4;
The system defines the following macro to describe where these report messages are sent,
# DEFINE _ crtdbg_mode_file 0x1
# DEFINE _ crtdbg_mode_debug 0x2
# DEFINE _ crtdbg_mode_wndw 0x4
With the help of the source code and msdn, I finally figured out the location of the message:
If _ crtdbgmode [nrpttype] is _ crtdbg_mode_debug, call outputdebugstring to send the report message to the debugger.
If _ crtdbgmode [nrpttype] is _ crtdbg_mode_wndw, a dialog box with three buttons is displayed: Terminate, retry, and ignore.
Let's look back at the assert macro. Obviously, if the expr is non-zero, the assert is successful, and the while loop is exited directly without executing _ crtdbgreport. If the expr is 0, the _ crtdbgreport is executed, if you choose to terminate, the application is terminated immediately. If you choose to retry, _ crtdbgreport returns 1. The program runs the following Assembly Statement, which interrupts the program, it is the same as when you set a breakpoint. If you select ignore, the program continues to run. By the way, # expr indicates converting expr to a string. For example, if assert (0 = I), # expr is "0 = I".
If _ crtdbgmode [nrpttype] is _ crtdbg_mode_file, the report information is written into the file indicated by _ crtdbgfile [nrpttype.
The non-Win32 Implementation of the trace macro is very simple, that is, the printf is called to directly output the report message.