Thanks Jeff.
I'd like to share some tips with you guys, which including the answer for Question 1 that Jeff has mentioned in the prev-mail.
The root cause of the core-dump of the process "c3gcommx" is "Exception Specification".
Exception Specification Basic
An exception specification describes which exceptions a function is allowed to throw. Exceptions not listed in an exception specification should not be thrown from that function. An exception specification consists of the keyword throw after the function's parameter list, followed by a list of potential exceptions:
void testFun(int param1,...) throw(int, c_Exception, const char *)
An exception specification isn't considered a part of a function's type. Therefore, it doesn't affect overload resolution. That said, pointers to functions and pointers to member functions may contain an exception specification.
An overriding virtual cannot extend the set of exceptions declared in the base class's function. However, it can narrow it.
A function with no exception-specification allows all exceptions. A function with an empty exception specification doesn't allow any exceptions
void testFun(){...}//Allows throw all exceptions.
void testFun2() throw() {...} // Do not allow throw any exceptions.
Enforcement of Exception Specification
Exception Specifications are enforced at runtime, it means:
1. In general, you only allowed to throw the exceptions which defined in the exception specification. If you try to throw a unexpected exception in the function-body, you are violating the rules (Exception Specification). In this case, the unexcepted() is called, unexcepted() invokes a user-defined function that was previously registered by calling set_unexcepted(). If no function was registered with set_unexcepted(), unexcepted() calls terminate() which may cause a core-dump.
2. The C++ compiler do not check the rules, it means, if you violated a rule, there is no error/warnings report provided by compilers.
Further more, this theory of C++ exception handling is quite different with Java implementation:
1. Java only allows throwing a known exception, it means that you can not violate any "Exception Specifications".
2. Java checks the violation at compile-time, you will get a error report when violated any rules.
The core-dump of process "c3gcommx" was caused by violating of exception specifications.
A Concrete Sample to test
OK, let's check this theory with a concrete sample. Suppose you can read C++ source code :).
I have defined a class "TestExceptionClass" and a main() to run whole test cases.
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
//Declare a class to hold some exception
class SampleException{};
class TestExceptionClass
{
public:
void AllowAllException()//Without any Exception Specifications.
{
throw "Exception From AllowAllException()";//const char *
};
void DONOT_AllowAnyException() throw() //Empty exception list, do not allow any exceptions.
{
throw "Exception From DONOT_AllowAnyException()";
}
void Normal_Call() throw(SampleException)
{
SampleException se;
throw se;
}
void Voliate_Call() throw(SampleException)
{
throw "Violate the rules! This exception will cause a crash!";
}
};
int main()
{
cout<<"---------------------Test Exception Specification--------------------"<<endl;
try
{
TestExceptionClass testInstance;
testInstance.Normal_Call();
}
catch(...)
{
cout<<"ERROR: UNKNOWN ERROR OCCURRED AND CATCHED IT."<<endl;
}
return 0;
}
In the function main(), the code snippet "catch(...)" try to catch any exception threw by TestExceptionClass.
First, We compile the file and execute it. Very good, we get a excepted result as below:
bash-3.00$ ./testex
---------------------Test Exception Specification--------------------
ERROR: UNKNOWN ERROR OCCURRED AND CATCHED IT.
bash-3.00$
Let's try to make a violation. It's quite easy, we just need to modified the main() to call "Voliate_Call()" instead of "Normal_Call()":
int main()
{
cout<<"---------------------Test Exception Specification--------------------"<<endl;
try
{
TestExceptionClass testInstance;
testInstance.Voliate_Call();
}
catch(...)
{
cout<<"ERROR: UNKNOWN ERROR OCCURRED AND CATCHED IT."<<endl;
}
return 0;
}
We got a crash after we executed the newer version:
bash-3.00$ ./testex
---------------------Test Exception Specification--------------------
terminate called after throwing an instance of 'char const*'
Aborted
Obviously, the violation can not be catch by catch-all-exception. Some guys have shouted out this "design-bug" for a long while, but there has no changes or enhancement made by the committee. This is indeed a regrettable thing.
The following links might be helpful for you:
A pragmatic look at Exception Specification http://www.gotw.ca/publications/mill22.htm
Exception safety and Exception Specification: Are they worth it? http://www.gotw.ca/gotw/082.htm
Further more, <Think In C++> and <C++ Prime> may be more popular, you can found some tips in those books.