Those two things in VC must have been used by anyone, but what is the difference between them? I just have time to study them. If there is a mistake, please make a brick.
Based on vc2005, the 32-bit xp platform passed the test. It is estimated that other versions of VC and operating systems are not universal.
1. Try... catch
This is defined in the C ++ language, and each c ++ has different implementations for it. it is easy to use. for example, we have a function that reads data about age. if <= 0 or> = 100, an exception is thrown:
Int readage (){
Int age = read age;
If (age <= 0 | age> = 100 ){
Throw ageexception (AGE );
}
Return age;
}
Ageexception is defined
Class ageexception {
Public:
Int errorage;
Ageexception (INT age ){
Errorage = age;
}
};
It is also relatively simple to use,
Try {
Int I = readage ();
Printf ("Age inputed is % d", I );
} Catch (ageexception e ){
Printf ("error. Age inputed = % d and is not valid.", E. errorage );
}
2. _ Try... _ try t
This is a keyword defined by VC rather than C ++. VC is compiling _ try... _ HANDLE t, the exception handling part will be added to the exception handling chain of the current thread according to the Windows Seh (structured exception) processing rules. this part is not detailed, so seh will search for articles on the Internet.
3. Differences between try... catch and _ Try... _ catch t
For the above ageexception, we can also use _ Try... _ HANDLE t for processing:
_ Try {
Int I = readage ();
Printf ("Age inputed is % d", I );
} _ Handler T (exception_execute_handler ){
Printf ("Age is not correct .");
}
However, for _ try... _ HANDLE t can handle exceptions (such as the following code), c ++ Exception Handling try .. catch cannot be captured (the catch segment cannot be executed ):
Try {
Int * P = NULL;
* P = 0;
} Catch (...){
Printf ("exception occured .");
}
Note: This is actually related to the compiler, vc2005 by/EH plus parameters to control, For details, see the http://msdn.microsoft.com/en-us/library/1deeycx5 (vs.80). aspx. Here we discuss the default situation, not to deal.
This is why. Let's take a closer look. When we throw an exception in the program, the debugger (such as Vc and windbg) will record the following event:
First-chance exception at 0x7c812afb (kernel32.dll) in trycatch.exe:Microsoft C ++ exception: Ageexception at memory location 0x0012fc98 ..
That is to say, in VC, Microsoft C ++ exception is thrown by throw. Only such exception can be captured by try... catch. Similarly, the above program can be loaded by windbg.
_ Try {
Int I = readage ();
Printf ("Age inputed is % d", I );
} _ Handler T (exception_execute_handler ){
Printf ("Age is not correct .");
}
The exception is C ++ exception, and the Exception Code is 0xe06d7363:
That is to say, the exception thrown by throw in C ++ is a special type of exception, which is implemented by Microsoft for VC ++. The Exception Code is 0xe06d7363. (The ASCII code 0x6d, 0x73, and 0x63 Is MSC)
Here we can draw a conclusion, try... catch and _ try... _ processing t is essentially the same thing. They all use the Windows seh processing mechanism at the root. the difference is:
-) Try... catch only processes the C ++ exception with the Exception Code 0xe06d7363 and does not care about other exceptions;
-) Try... catch does some extra work for the compiler, but the final implementation is to sum up with _ Try... _ catch t to Seh.
-) Try... catch has some additional information about the exception (What exception is caught. not like _ try... _ processing T, which must be determined using predictioncode)
When I think of this, I think of the following question: how does the VC ++ compiler know the catch exception information? In other words, for the following code, we know that an exception has occurred, but how can we get the exception information?
_ Try {
Int I = readage ();
Printf ("Age inputed is % d", I );
} _ Handler T (exception_execute_handler ){
Printf ("Age is not correct .");// How do I know the ageexception thrown by throw in readage?
}
For debugging convenience, modify the exception class and code that throws exceptions, and pass the error age and a message when creating the exception.
Class ageexception {
Public:
Int errorage;
Char * P;
Ageexception (INT age, char * MSG ){
Errorage = age;
P = MSG;
}
};
Int readage (){
Int age = 123 ;//
If (age <= 0 | age> = 100 ){
Throw ageexception (age, "Age is outof range .");
}
Return age;
}
Load and run with windbg. If a C ++ exception occurs, use. EXR-1Command to view recent exceptions:
It can be seen that this exception is the c ++ exception (0xe06d7363 type) discussed earlier, with three parameters, each of which is 0x19930520, 0x0012fca4, 0x0020.bc8, respectively. because I have not found the meaning of the parameters in the C ++ exception, I can only guess (if anyone knows, please kindly advise ).
Considering that the exception type thrown by the code that throws an exception is ageexception, it is natural that the thrown exception is stored as a pointer in the parameter. Because there is no data, it can only be tested one by one. Use the commandDT trycatch! Ageexception addressTo display the address content in trycatch.exe (compiled program name is trycatch.exe) according to the ageexception class:
Sure enough, the first parameter 0x19930520 is not what we want. When we enter the second parameter, the content in the address is the same as expected. It is the content in the exception we throw. this verifies the conjecture. try... the catch workflow is as follows:
-) When compiling try... catch, the compiler also uses Windows seh to handle only C ++ exceptions (0xe06d7363 type;
-) When an exception is thrown (throw), the generated instance address of the exception class is saved in the second parameter of the exception information.
-) When a catch exception occurs, read the address from the 2nd parameters of the exception information and convert it to an instance of the exception class for the program to use.
To use _ Try... _ simulate t to simulate the above process, the program can be changed:
_ Try {
Int I = readage ();
Printf ("Age inputed is % d", I );
} _ Extract T (extract (getexceptioninformation (), exception_execute_handler ){
Printf ("exception happene .");
}
Void extract (lpexception_pointers p ){
Int d = p-> predictionrecord-> numberparameters; // number of parameters, which is not used here
Unsigned int * Ex = (unsigned int *) P-> predictionrecord-> predictioninformation [1]; // The second parameter
Ageexception * E = (ageexception *) Ex; // convert to get an instance of the exception class
Printf ("==> % d \ n", e-> errorage); // you can find the exception information.
Printf ("==> % s \ n", e-> P); // you can find the exception information.
}
Run, which is consistent with the expected results.
Finally, we can draw a conclusion (I don't know if this is completely correct ):
Try... catch is the compiler for _ try... _ handle t is a package. This package only processes the C ++ exception type, but provides a more convenient way to pass the thrown exception information, so that programmers can easily handle exceptions, you do not need to manually retrieve the exception information as in the preceding example.