Use ScopeGuard to monitor internal variables in the operating environment
Smilemac
1. Introduction to ScopeGuard
We know that when using structured abnormalities to write a function of high reliability, especially if there is side effects (Side Effect), then when the execution fails, it is necessary to maintain resource consistency, trivial mess block. It will make the program readability is very poor, and it seems ugly, the ScopeGuard technology written by Petru Marginean and Andrei Alexandrescu has a good effect in maintaining resource consistency when procedure is abnormal. The principle is to use an abnormality. The stack will unwind, all partial and temporary variables in the TRY block will be released normally, and the destructor's destructor is characterized by normal calls. If you define a class, do some specific resource consistency works in its parallelism function, and in advance in the TRY block, you will always be executed when there is an abnormality.
ScopeGuard includes the following classes and functions:
Class ScopeGuardImplbase: Provides the base class of the monitoring class, you can derive a number of derived classes that can handle different quantities of parameters from this class, it is worth noting that the designer of this base class is not a virtual function, the author uses one Very interesting skills to get polymorphism. Class ScopeGuardImpl1: This is a derived class that handles a parameter, and the user can simulate the monitoring class of multiple parameters in this form. Void ScopeGuardImplbase :: Dismiss () Const throw (): This is a function that cancels the monitor, if it is not called until the function returns, the action will be executed. There is also auxiliary class and auxiliary type definition: Template
For details, see http://www.cuj.com/documents/s=8000/20jcexp1812alexandr/.
2. Problems in runtime monitoring
We know that there are two programs that are difficult to debug, one is a parallel program uncertain dynamic characteristics, such as multi-threaded programs, running time process status and debugging, and the other is closely related to time. Programs, such as real-time systems, is not convenient for debugging. For these two systems, the main variable monitoring means is to write variable values into log files or other output devices appropriately. But what is the situation when an abnormality occurs, the traditional method is to capture exceptions with Catch, then write the variable to the log, as shown below: Void f (void) {int State1_, state2_; try {do something;} catch ...) {log ("State1 = 0x% x / n", state1_); log ("State2 = 0x% x / n", state2_);}} Obviously, this practice has a lot of disadvantages:
The first is that the program is structural, it is more ugly. Second, the variable must be defined outside the TRY block, otherwise it can only be passed through abnormal variables. When there are many variables that require monitoring, this approach is unrealistic.
Is there a better way? The answer is that it is in ScopeGuard.
3. Monitor local variables using ScopeGuard (why the topic wants to monitor local variables, first wait for a while, will be introduced later.)
Because our log function needs to handle at least two parameters, one is a string represents the variable name, and the other is the value of the variable, so it is necessary to implement a ScopeGuardimp class that can handle two parameters. This reader can imitate the PETRU's programself. This article is not described. This article describes another method.
First implement a MyLog's function object, as follows Template
Void Operator () (v Value) {log (format_, value);} private: cmylog ();
Then define an auxiliary function: Template
The monitor is now used in the above functions and Safeguard. Void f (void) {int State1_, State2_; Scopeguard Guard1 = Makeguard ("State1 = 0x% X / N", State1_), Byref (state1_)); ScopeGuard Guard2 = Makeguard (WriteLog ("Statelog (" Statelog ("Statelog (" Statelog / N ", state2_), byref (state2_)); do something; guard1.dismiss (); guard2.dismiss ();
Ok, I have written so much, and now I can finally write a program that monitors internal variables in a unified and elegant way. However, careful readers may have discovered that there is no problem with this code to monitor global or static variables, but monitoring local Is the automatic variable no problem? Due to the optimization of the compilation program, do God 1 must first be STATE1_ release (DESTROY)? The answer is affirmative, this has been guaranteed by C standards, and the C standard stipulates that the release of the temporary variable will be performed in the reverse order of the creation, and the temporary variable is held in the reverse order of the creation. These automatic and static variables are released in the opposite order. Note that Makeguard generates a temporary variable, which occurs when the sector is the temporary variable. Therefore, the above designer is: Guard2 (bonded temporary object), Guard1 (bonded temporary object), State1_ and State2_. This is especially useful for monitoring the relevant state variables. 4. Conclusion This paper introduces SAFEGUARD an application in writing troubleshooting code, in this way, the monitoring code written in this manner avoids the traditional Direct use of the Try ... Catch structure, the code is bloated, structurally differential, etc. It is also easy to compile statements in the software release, which does not affect the neat of the program, and the other related secondary and functions have a relatability (Reusibility). The author believes that due to the above advantages, this method has a good value of use.
5. Reference Andrei Alexandrescu and Petru Marginean, "Change the Way You Write Exception-Safe Code - Forever", http://www.cuj.com/documents/s=8000/cujcexp1812alexandr