Asger Joergensen <
XXXX@XXXXX.COM >writes:
Quote
>If code isn't written to be reentrant,
What does that mean ??
When a function is interrupted and that interruption starts the
function again from the top, does it work? Recursive functions are
one example of code that must be re-entrant. Stuff running with
asynchronous interrupt handlers requires re-entrancy safety, and, of
course, manual interruptions (like running the event loop in the
middle) means that the event loop could invoke your function as well.
For example, assume contrived_resize() always assumes that its member
is not null (as copying str implies it is a valid pointer!):
class X
{
public:
X() : buf(new char[10]), size(10) { /*...*/ }
X(X const & rhs) : buf(new char[10]), size(10) { /*...*/ }
~X() { delete [] buf; }
// basically works but a "bad function"
void contrived_resize(std::size_t newsize)
{
std::vector<char>copy(str, str + size);
delete str[];
str = new char[newsize];
std::memcpy(str, copy.begin(), std::min(copy.size(), newsize));
}
private:
char const * buf;
std::size_t size;
};
As long as new doesn't throuw in contrived_resize, it will work just
fine. (Well, not tested, but you get the point.)
However, if contrived_resize calls to other code between the delete[]
and the new, then the object is left in a bad state.
void contrived_resize(std::size_t newsize)
{
std::vector<char>copy(str, str + size);
delete str[];
Application->Process_Messages(); // Obviously dangerous
str = new char[newsize];
std::memcpy(str, copy.begin(), std::min(copy.size(), newsize));
}
Other types of examples include:
* short-lived objects that process a list of things and then delete
themselves. Suppose each processing chunk is called by a timer, if
the processor invokes the event loop, a nested timer call could be
made, and the SECOND invocation could complete the work and cause it
to delete itself. Then when the stack unwinds we find ourselves in
the middle of the first invocation and it is running in a deleted
object.
* static local data is usually a sign of non-reentrant code
Etc.
--
Chris (TeamB);