1.1 Basic ConceptsAssertion is a simple, effective, and practical technique that exposes errors during runtime. They help you identify errors more easily earlier, making the entire debugging process more efficient. Assertions are Boolean debugging statements used to check whether the value of a certain condition is always true when the program runs normally. They can expose errors to programmers at runtime. The biggest advantage of using assertions is that you can find errors in the locations where errors occur. Assertions have the following characteristics: N assertions are used to detect runtime errors, and the errors found are about program implementation. The Boolean expression in N assertion shows the validity of an object or State rather than correctness. N assertions exist only in the debug version after Conditional compilation, rather than in the release version. N assertions cannot contain program code. N assertions are intended to provide information to programmers rather than users. The most fundamental advantage of using assertions is to automatically discover many errors generated during runtime, but assertions cannot discover all errors. Assertions check the validity of the program rather than the correctness. errors can be limited to a limited range through assertions. When the assertions are false and the debugger is activated to display the error code, the cause of the failure is usually checked. _ Asserte macro (which belongs to the C Runtime database) can also display failure assertions when the assertions fail.
1.2 assert in C)The assert macro plays an important role in the debugging of C language programs. It is used to detect situations that do not happen, indicating that once such a situation occurs, the program will actually execute an error, such as the strcpy function: char * strcpy (char * strdest, const char * strsrc) {char * address = strdest; Assert (strdest! = NULL) & (strsrc! = NULL); While (* strdest ++ = * strsrc ++ )! = '/0'); return address;} contains assert (strdest! = NULL) & (strsrc! = NULL). It means that the address of both the source and target strings cannot be empty. Once it is empty, the program will actually execute an error and lead to a abort. Assert macro is defined as: # ifdef ndebug # define assert (exp) (void) 0) # else # ifdef _ cplusplusextern "C" {# endif _ cribd void _ cdecl _ assert (void *, void *, unsigned ); # ifdef _ cplusplus} # endif # define assert (exp) (void) (exp) | (_ assert (# exp, _ file __, _ line _), 0) # endif/* ndebug */If the program is not in debug mode, the assert macro does nothing. In debug mode, it is actually a call to the _ assert () function. This function outputs the wrong file name, code line, and conditional expression. It is important to remember that assert is essentially a macro, not a function. Therefore, expressions with side effects cannot be put into assert's "parameter.
1.3 Exit)The standard C Library provides two functions: Abort () and exit (). They can forcibly terminate the running of the program and the declaration is in the header file <stdlib. h>. These two functions cannot detect exceptions, but they are often used to terminate the program after exceptions occur in the C program. For the exit function, you can use the atexit function to "Hook" another function for the exit event, which is similar to the "Hook" in Windows programming ). After the program outputs the "atexit attached function", it is terminated. Even if we do not call the exit function, when the program exits, the function attached with atexit will still be executed. Atexit can be executed multiple times and attached to multiple functions. The execution sequence of these functions is the first execution of the subsequent attached functions. In Visual C ++, If you terminate a program using the abort function (this function does not contain parameters, the prototype is void abort (void, an error prompt dialog box will pop up when running in debug mode.
1.4 assertions in MFC
1.4.1 assert (Boolean expression)Generally, assert (x) macro is used to check the validity of variables in VC. Assert is used to check whether the expression is false or null. If the expression is false, an exception is thrown. In MFC, The assert macro is widely used. Its advantage is that even if a wm_quit message appears, the asserted message box can be displayed. When the assert fails and an exception is thrown, a dialog box pops up and reports the location where the assert fails. And allows you to choose to continue running (ignore) or terminate (abort) the program. (Of course, it is very dangerous to choose to continue running) Selecting retry will start the debugging software to debug the program. In addition, the assert macro only works in the debugging version. In the debugging version, the assert (f) macro is expanded to do {If (! (F) & afxassertfailedline (this_file, _ line _) afxdebugbreak ();} while (0) will be expanded to (void) 0) in the release version) therefore, codes that change the internal state of the program cannot be placed in the assert macro. Otherwise, the Code may be abnormal in the release.
1.4.2 verify (Boolean expression)You can use the verify macro if you want to check the validity of the function in the release version. The Verify macro simplifies the function return value check and is generally used to check the windows API return value. Different verify macros and assert macros work in the same way as verify in the release version. However, using verify may lead to unfriendly user interfaces, therefore, it is best not to use this macro to completely separate program code from debugging code.
1.4.3 assert_valid (pointer to the cobject derived class Object)The validity check of an object depends on its own State and logic. Therefore, it cannot be correctly determined outside the object, A time-saving and effective method is to check the validity of the object. The object itself is responsible for the validity check. The MFC uses the member function void cobject: assertvalid () const to check the validity of the object, therefore, the new class must be a cobject derived class (almost all classes in MFC are derived from cobject) because the assertvalid function of the C ++ polymorphism derived class will be called correctly. The const in the function definition indicates that the value of the member variable cannot be changed in the function body. All we need to do is to reload assertvalid and check the validity of the object state. In assertvalid, we can not only check the correctness of the data, but also check the logic of the data. In addition, the assert_valid macro is defined in MFC to perform the security object check. The assert_valid macro expands afxassertvalidobject and first checks the validity of the pointer. This avoids the following errors: cview * Pv = NULL; PV-> assertvalid (); // The safe method is to use assert_valid (pview ); the assert_valid macro calls the overloaded assertvalid function to determine whether the pointer to the object of the cobject derived class is valid. Whenever you get an object from the cobject derived class, you should call the assert_valid macro before any operation on this object. Like assert macros, assert_valid macros only play a role in debugging versions.
1.4.4 othersAssert_kindof (Class Name, pointer to the cobject derived class Object): This macro is used to verify whether the pointer to the cobject derived class object is derived from a special class and calls the assert_valid macro before calling it. It can only be used in special cases, such as detecting the object type problems that may be missed by the compiler. MFC also has two assert macro variants without formal files: assert_pointer (pointer, pointer type), assert_null_or_pointer (pointer, pointer type ).
1.5 when to use assertionsThink of assertion as a simple method of creating a fence that exposes errors as they pass through. U check function input u check function output u check object's current state U adhere to the rationality and consistency of logical variables u check class's invariant public member functions than private and protected member functions need more comprehensive assertions. Improper use of assertions may cause errors. Assertions should detect states that are never possible when the program runs normally. Assertions are used to reveal errors, not to correct runtime errors.
1.6 Defensive Programming)Assertions reveal runtime errors (in debugging versions) to programmers during debugging, while Defensive Programming allows users to run programs (in released versions, the program can continue to work in case of exceptions. In fact, defensive programming requires the program to return a "safe" value when detecting an accident (for example, the Boolean function returns false, and the pointer and handle return NULL values ), an error code or an exception is thrown to solve the problem. Specific defensive programming techniques include: processing invalid function parameters and data, program failure when a problem occurs, checking the error code returned by the critical function, and handling exceptions. Standard issues that require Defensive Programming include incorrect input data, insufficient memory or hard disk space, failure to open a file, access from external devices, failure to connect to the network, or even errors in the program, the purpose is to keep the program running. If your program is defensive, do not forget to use assertions. If you use assertions, do not forget Defensive Programming. It is best to combine these two technologies.