Problem with throwing class objects
-
I seem to have stubled across my second bug (in about 8 hours worth of using this compiler). Now, I've always used what I believed to be the standard way of throwing class exceptions (as shown in Stroustrup):
class AWobbley { char *m_msg; public: AWobbley(const char *msg); ... }; ... throw AWobbley("AGHRR!"); ... catch (AWobbley &e) { ... do something with e.m_msg }
The problem came up when the exception class stored a dynamically constructed message and, thus, needed a destructor to delete it. In VC++ this destructor is called before the exception handler is entered. This, of course, completely messes up the whole technique.:mad: I haven't yet found a bug report on the Microsoft site. Anyone else with this problem? Yes, of course there are work arrounds like passing a pointer to a newed object and deleting it at the bottom of the exception handler, but it's ugly and something I wouldn't want to keep for another compiler. -
I seem to have stubled across my second bug (in about 8 hours worth of using this compiler). Now, I've always used what I believed to be the standard way of throwing class exceptions (as shown in Stroustrup):
class AWobbley { char *m_msg; public: AWobbley(const char *msg); ... }; ... throw AWobbley("AGHRR!"); ... catch (AWobbley &e) { ... do something with e.m_msg }
The problem came up when the exception class stored a dynamically constructed message and, thus, needed a destructor to delete it. In VC++ this destructor is called before the exception handler is entered. This, of course, completely messes up the whole technique.:mad: I haven't yet found a bug report on the Microsoft site. Anyone else with this problem? Yes, of course there are work arrounds like passing a pointer to a newed object and deleting it at the bottom of the exception handler, but it's ugly and something I wouldn't want to keep for another compiler.You need to add the copy constructor to AWobbley and program will behave as expected. If you comment out AWobbley(const AWobbley &a), you'll see two dtor calls and only one ctor - looks like a bug. And the funniest thing is that program doesn't call copy ctor when it is defined.
class AWobbley
{
public:
AWobbley() { printf("def ctor\n"); }
AWobbley(const char *msg) : m_msg(msg) { printf("ctor\n");}
AWobbley(const AWobbley &a) { printf("copy ctor\n"); m_msg = a.m_msg; }
~AWobbley() { printf("dtor\n"); }
void print() { printf("%s\n", m_msg); }
private:
const char *m_msg;
};void main( void )
{
try
{
throw AWobbley("AGHRR!");
}
catch (AWobbley &e)
{
printf("exception handler\n");
e.print();
}
}Tomasz Sowinski -- http://www.shooltz.com
-
You need to add the copy constructor to AWobbley and program will behave as expected. If you comment out AWobbley(const AWobbley &a), you'll see two dtor calls and only one ctor - looks like a bug. And the funniest thing is that program doesn't call copy ctor when it is defined.
class AWobbley
{
public:
AWobbley() { printf("def ctor\n"); }
AWobbley(const char *msg) : m_msg(msg) { printf("ctor\n");}
AWobbley(const AWobbley &a) { printf("copy ctor\n"); m_msg = a.m_msg; }
~AWobbley() { printf("dtor\n"); }
void print() { printf("%s\n", m_msg); }
private:
const char *m_msg;
};void main( void )
{
try
{
throw AWobbley("AGHRR!");
}
catch (AWobbley &e)
{
printf("exception handler\n");
e.print();
}
}Tomasz Sowinski -- http://www.shooltz.com
Now that is weird. I'd say definitely a compiler bug. Thanks for the work arround. :rose:
-
Now that is weird. I'd say definitely a compiler bug. Thanks for the work arround. :rose:
The stuff that happens without copy ctor looks like bug. Behavior with copy ctor defined may be optimization - the exception object is created 'in-place' once. Tomasz Sowinski -- http://www.shooltz.com