问题
I have derived a class from std::exception:
class exc : public std::exception
{
public:
exc(const text::_char *) throw();
exc(const exc &) throw();
virtual ~exc() throw();
text::_char *m_what;
};
I have two wrapper functions to throw my exception type:
PS: dbg_out refers to std::cout. text is a descendant of std::basic_string<< char >>.
void throw_exception(const text::_char *p_format, ...)
{
va_list l_list;
text l_message;
va_start(l_list, p_format);
l_message.format_va(p_format, l_list);
va_end(l_list);
throw exc((const text::_char *)l_message);
}
void throw_exception_va(const text::_char *p_format, va_list p_list)
{
text l;
exc l_exc((const text::_char *)l.format_va(p_format, p_list));
dbg_out << l_exc.m_what;
throw l_exc;
}
And the main function:
int main(int, char **)
{
try
{
throw_exception("hello world!");
return 0;
}
catch(const std::exception &p)
{
return 0;
}
}
My program crashes with this message:
hello world!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I use gcc compiler (latest MinGW version)
My program does not enter the catch handler in the main function. It doesn't call the copy constructor of class exc. It looks like the code generated by gcc, does not recognize exc as a descendant of std::exception.
What am I doing wrong?
回答1:
I'd wager your problem is on this line:
throw exc((const text::_char *)l_message);
You mention text
is derived from basic_string<char>
. There is no supported cast from basic_string<char>
to const char*
. So unless you're providing your own conversion operator in the derived class, you're kind of off into undefined/unspecified behavior here. Try changing the above line to:
throw exc(l_message.c_str());
回答2:
This is what I wrote on dec. 5th:
The memory copied by the constructor of exc has been deleted before it was copied. Access Violation guaranteed! I have learned one more thing about this wonderful programming language (what happens behind the scenes when you 'throw exc(some_deleted_memory)'.
<< end dec. 5th>>
This is not the real problem. The real problem is that gcc-compiler (with the options:)
gcc -fexceptions -Wnoexcept -fno-use-cxa-get-exception-ptr -include .\pch.h -g3 *.cpp
-l libstdc++ -o vlb.exe
does not like exceptions to be thrown against the 'throw()' specifications of the function declarations. When 'throw_exception()' is declared as
void throw_exception() throw(const std::exception &);
all is fine.
I have always thought that (at least software-) exceptions may occur at every call-statement, and the stack unwind procedure must be able to deal with that. I don't like the idear that I would have to specify what type of exceptions could possibly leave a function for every function I write.
Somehow, I should be able to specify that any type of software exception could leave any function I write, on gcc's commandline. But how? I will post a new question for this new topic.
Thanks to all who have thought along for me.
来源:https://stackoverflow.com/questions/8392237/extending-the-stdexception-class-program-wont-execute-the-appropriate-catch