|  | Should the assignment of an exception class call std::exce |  | |
| | | Niels Dekker - no return |  |
| Posted: Sun Jun 01, 2008 9:03 am Post subject: Should the assignment of an exception class call std::exce |  |
| |  | |
Should the assignment operator of a custom exception class derived from std::exception, do an std::exception assignment? For example:
class MyException : public std::exception { public: MyException & operator=(const MyException & arg) { // Good Coding Style? static_cast<std::exception &>(*this) = arg; return *this; } };
I'm asking because there's a bug in the std::exception::operator= implementation I'm currently using, as reported by Jouni Kiviniemi at connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=328570
Actually it caused a unit test crash in a revision of ITK's ExceptionObject class <www.itk.org> that I committed last week. So I think I have to remove the std::exception::operator= call anyway...
Kind regards, -- Niels Dekker LINK Scientific programmer at LKEB, Leiden University Medical Center
[ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Alberto Ganesh Barbati |  |
| Posted: Mon Jun 02, 2008 12:36 am Post subject: Re: Should the assignment of an exception class call std:: |  |
| |  | |
Niels Dekker - no return address ha scritto:
| Quote: | Should the assignment operator of a custom exception class derived from std::exception, do an std::exception assignment? For example:
|
Any derived class implementing operator= should call the inherited operator= in a way or another. It's not a matter of style, omitting to do so would produce incorrect results.
| Quote: | class MyException : public std::exception { public: MyException & operator=(const MyException & arg) { // Good Coding Style? static_cast<std::exception &>(*this) = arg; return *this; } };
|
I actually recall I saw this as a "recommended" idiom somewhere. A better syntax avoiding the cast would be:
std::exception::operator=(arg);
but it's known to confuse some older compilers, especially when the base class does not define operator= explicitly.
| Quote: | I'm asking because there's a bug in the std::exception::operator= implementation I'm currently using, as reported by Jouni Kiviniemi at connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=328570
|
Ugh. Then discussing whether the above approach is good style or not is totally pointless, because such approach doesn't solve your problem. In fact you will still be calling std::exception::operator= even if the syntax may look exotic.
| Quote: | Actually it caused a unit test crash in a revision of ITK's ExceptionObject class <www.itk.org> that I committed last week. So I think I have to remove the std::exception::operator= call anyway...
|
You are facing a lost battle. If you don't call the base operator= the code will produce the wrong result, because you won't be copying the string to the target object. Yet, if you do call operator= you have a memory leak...
Given that this is a bug Microsoft should fix, the only workaround is to avoid calling std::exception::operator=. For example:
class MyException : public std::exception { public: MyException & operator=(const MyException & arg) { if (this != arg) { // This is only to work around a bug in the base class // NOT a generally valid approach to assignment this->~MyException(); new(this) MyException(arg.what()); } return *this; } };
Not the best code, but I've seen worse. And it works, provided MyException has a constructor that passes its argument to the constructor of the base class.
HTH,
Ganesh
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Niels Dekker - no return |  |
| Posted: Tue Jun 03, 2008 3:03 am Post subject: Re: Should the assignment of an exception class call std:: |  |
| |  | |
| Quote: | Should the assignment operator of a custom exception class derived from std::exception, do an std::exception assignment?
|
Alberto Ganesh Barbati replied:
| Quote: | Any derived class implementing operator= should call the inherited operator= in a way or another. It's not a matter of style, omitting to do so would produce incorrect results.
|
I don't think that's true for /any/ derived class. For instance if its base class doesn't contain any data...
| Quote: | class MyException : public std::exception { public: MyException & operator=(const MyException & arg) { // Good Coding Style? static_cast<std::exception &>(*this) = arg; return *this; } };
|
Alberto wrote:
| Quote: | A better syntax avoiding the cast would be: std::exception::operator=(arg); but it's known to confuse some older compilers, especially when the base class does not define operator= explicitly.
|
Okay, thanks!
| Quote: | I'm asking because there's a bug in the std::exception::operator= implementation I'm currently using, as reported by Jouni Kiviniemi at connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=328570
|
Actually my problem isn't just the memory leak reported by Jouni Kiviniemi. I still need to support MSVC 2003, which has a slightly different problem, as I just posted at microsoft.public.vc.language: "VC7.1 std::exception assignment operator bug (crash) a known issue?" LINK
| Quote: | You are facing a lost battle. If you don't call the base operator= the code will produce the wrong result, because you won't be copying the string to the target object. Yet, if you do call operator= you have a memory leak...
|
Well... my example class, MyException, was overly simplified. The actual class I was working on, itk::ExceptionObject, has its own string data, and overrides the what() function. Feel free to take a look: LINK LINK
| Quote: | Given that this is a bug Microsoft should fix, the only workaround is to avoid calling std::exception::operator=. For example: class MyException : public std::exception { public: MyException & operator=(const MyException & arg) { if (this != arg) { // This is only to work around a bug in the base class // NOT a generally valid approach to assignment this->~MyException(); new(this) MyException(arg.what()); } return *this; } };
|
Thanks! Please note that you assume that std::exception has a constructor that accepts a char pointer. Which is a Microsoft specific extension. But still, I wonder if I can't just get away with skipping the std::exception assignment, and only copy the derived exception data... Let's forget about compiler issues for a moment. Why would a custom exception class need to do an std::exception assignment in the first place? The current Working Draft (www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2606.pdf) specifies std::exception's assignment as follows [exception]:
exception& operator=(const exception&) throw(); Effects: Copies an exception object. Remarks: The effects of calling what() after assignment are implementation-defined.
What does it mean to copy an std::exception object? std::exception isn't specified to have any data. It does not even seem to be EqualityComparable. (Please correct me if I'm wrong! It doesn't have any comparison operator, right?) So what difference does it make, assigning or not?
Kind regards,
Niels
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
|
|