siddhu said:
I think I understand the term "Exception neutral" which means
exception should get propagated to the caller without loosing the
integrity of the program. I did not understand the term "Exception
safe" correctly. Does it mean that the code which will be called
exception safe should not throw any exception and maintain the
integrity of the program? How does it differ from "Exception neutral"?
Your input would be of great help.
AFAIK exception safety does not mean the code doesn't throw exceptions.
It means that if an exception is thrown anywhere, it will not leak
anything.
For example, this is not exception-safe:
void foo()
{
int* array = new int[amount];
do_something_with(array);
delete[] array;
}
Well, if do_something_with() has a nothrow guarantee, this is
exception safe.
This is:
void foo()
{
std::vector<int> array(amount);
do_something_with(array);
}
AFAIK exception neutral only mean that upon exception, if the state of
the program was modified, the state of the program remains valid when
going out of the scope.
In practice, any resource acquired should be released (memory, mutex,
file, ...) and there shouldn't be data in inconsistent state
(typically dangling pointers).
IIRC exception safe means that the former state of the system is
preserved.
The usual example is the copy operator of a class storing dynamically
allocated data:
This is unsafe:
Foo& operator=(Foo const & foo)
{
if( myData != foo.myData )
{
delete myData;
myData = new MyData(foo.myData); // if throw here, this->myData is
dangling pointer
}
return *this;
}
This is exception neutral (assuming null myData is a valid state):
Foo& operator=(Foo const & foo)
{
if( myData != foo.myData )
{
delete myData;
myData = NULL;
myData = new MyData(foo.myData); // if throw here, this->myData is
lost
}
return *this;
}
This is exception safe:
Foo& operator=(Foo const & foo)
{
if( myData != foo.myData )
{
MyData* newData = new MyData(foo.myData);
std::swap(newData, myData); // this is nothrow
delete newData;
}
return *this;
}