**Env: Win2000, VC++ 6.0 SP 5**
I'm getting an error on the ExceptionTest::testAssignment() when i run CppUnitTestApp.exe... The second reference 'other' provided to 'checkIsSame( e, other )' always returns "Unknown Exception" when the 'otherWhat' string is constructed within checkIsSame... If i swap the arguments.. i.e checkIsSame( other, e ) the 'e' object fails... and other passes... if i cut and paste checkIsSame into the body of testAssignment both strings are created without a problem... damn!
I've tried the 'release' version but still get and error.... Anyone seen this before?
thx
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I made mistake... the 'assigned' class is alway the one that fails... seems to be related to the inherited assignment made in
Exeception::operator=()
i.e. exception::operator=(other)
...
The only way i've been able to work around the problem is to copy the checkIsSame behaviors to testAssignment() method...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
doc/FAQ:
2.3) Why does the test ExceptionTest.testAssignment failed in
CppUnit test suite?
- I've never been able to figure out why that test fails. It
seems to be specific to VC++ since the test passes with gcc.
If you can figure out the failure, please let us know!''
I sent email to all of the addresses that I found and got no response. So here I'll try again...
This is happening because the C++ libraries that are shipping with MSVC are slicing the exception in the assignment code. The real fact of the matter is that there are a number of operations in the test code that are doing this, but the compiler is "smart" enough to resolve the function addresses at compile time for most of them due to the fact that the objects are instantiated in the function, sliced, and then used in the same function (so the compiler knows what the vtable should be). I can break a couple of the other exception code tests by putting the actual assertions into functions which get called rather than keeping them in the same function where the objects are instantiated.
So- what *exactly* is happening? MSVC's implementation of std::exception::operator=() is doing a "trick" to copy the exception, it's destructing it and then constructing it in-place. The code likely looks something like:
exception::operator=(const exception& e)
{
delete this;
new (this) exception(e);
}
Pretty sloppy, due to the fact that it's guaranteeing that anything derived from execption will *be* exception upon completion of this function.
I have confirmed this behaviour with Pete Becker of Dinkumware, the implementors of MS's Standard Library. Unfortunately he's told me that they didn't actually do exception, and he doesn't even have the code. I hope that he can get it to the right people because it's a pretty serious deficiency, but I would think that in the general case, #define'ing out the call to exception::operator=() in CppUnit::Exception::operator=() for MSC_VER would solve the problem. Alternatively the MSVC implementation of CppUnit could just set the exception::what member by hand, but since CppUnit::Exception doesn't use that, it's probably not necessary to do even that.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Actually it is completely safe to derive from std::exception, assuming you have a conforming compiler. As I wrote previously, the "bug" is in the assignment operator of CppUnit::Exception::operator=(). At least, that's where the MSVC failure is occurring since MS mis-implemented std::exception::operator=().
This deficiency, and a work around, has been posted to the maintainers but there has been no response (and it's been two months?).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
**Env: Win2000, VC++ 6.0 SP 5**
I'm getting an error on the ExceptionTest::testAssignment() when i run CppUnitTestApp.exe... The second reference 'other' provided to 'checkIsSame( e, other )' always returns "Unknown Exception" when the 'otherWhat' string is constructed within checkIsSame... If i swap the arguments.. i.e checkIsSame( other, e ) the 'e' object fails... and other passes... if i cut and paste checkIsSame into the body of testAssignment both strings are created without a problem... damn!
I've tried the 'release' version but still get and error.... Anyone seen this before?
thx
I made mistake... the 'assigned' class is alway the one that fails... seems to be related to the inherited assignment made in
Exeception::operator=()
i.e. exception::operator=(other)
...
The only way i've been able to work around the problem is to copy the checkIsSame behaviors to testAssignment() method...
doc/FAQ:
2.3) Why does the test ExceptionTest.testAssignment failed in
CppUnit test suite?
- I've never been able to figure out why that test fails. It
seems to be specific to VC++ since the test passes with gcc.
If you can figure out the failure, please let us know!''
I sent email to all of the addresses that I found and got no response. So here I'll try again...
This is happening because the C++ libraries that are shipping with MSVC are slicing the exception in the assignment code. The real fact of the matter is that there are a number of operations in the test code that are doing this, but the compiler is "smart" enough to resolve the function addresses at compile time for most of them due to the fact that the objects are instantiated in the function, sliced, and then used in the same function (so the compiler knows what the vtable should be). I can break a couple of the other exception code tests by putting the actual assertions into functions which get called rather than keeping them in the same function where the objects are instantiated.
So- what *exactly* is happening? MSVC's implementation of std::exception::operator=() is doing a "trick" to copy the exception, it's destructing it and then constructing it in-place. The code likely looks something like:
exception::operator=(const exception& e)
{
delete this;
new (this) exception(e);
}
Pretty sloppy, due to the fact that it's guaranteeing that anything derived from execption will *be* exception upon completion of this function.
I have confirmed this behaviour with Pete Becker of Dinkumware, the implementors of MS's Standard Library. Unfortunately he's told me that they didn't actually do exception, and he doesn't even have the code. I hope that he can get it to the right people because it's a pretty serious deficiency, but I would think that in the general case, #define'ing out the call to exception::operator=() in CppUnit::Exception::operator=() for MSC_VER would solve the problem. Alternatively the MSVC implementation of CppUnit could just set the exception::what member by hand, but since CppUnit::Exception doesn't use that, it's probably not necessary to do even that.
There is a note in ANSI C++ Stardard, section 18.6.1 :
The effects of calling what() after assignment are implementation-defined.
So the ExceptionTest.testAssignment() seems not portable among different C++ compilers.
In VC, even the virtual destructor doesn't work correctly after the call to std::exception::operator=()
Then it seems not safe to derive a subclass from std::exception.
Has anybody got a work around?
Actually it is completely safe to derive from std::exception, assuming you have a conforming compiler. As I wrote previously, the "bug" is in the assignment operator of CppUnit::Exception::operator=(). At least, that's where the MSVC failure is occurring since MS mis-implemented std::exception::operator=().
This deficiency, and a work around, has been posted to the maintainers but there has been no response (and it's been two months?).