clear explanation sought: throw() and stack unwinding
Posted
by
Jerry Gagelman
on Programmers
See other posts from Programmers
or by Jerry Gagelman
Published on 2011-03-10T23:32:02Z
Indexed on
2011/03/11
0:18 UTC
Read the original article
Hit count: 503
c++
I'm not a programmer but have learned a lot watching others. I am writing wrapper classes to simplify things with a really technical API that I'm working with. Its routines return error codes, and I have a function that converts those to strings:
static const char* LibErrString(int errno);
For uniformity I decided to have member of my classes throw an exception when an error is encountered. I created a class:
struct MyExcept : public std::exception {
const char* errstr_;
const char* what() const throw() {return errstr_;}
MyExcept(const char* errstr) : errstr_(errstr) {}
};
Then, in one of my classes:
class Foo {
public:
void bar() {
int err = SomeAPIRoutine(...);
if (err != SUCCESS) throw MyExcept(LibErrString(err));
// otherwise...
}
};
The whole thing works perfectly: if SomeAPIRoutine
returns an error, a try-catch block around the call to Foo::bar
catches a standard exception with the correct error string in what()
.
Then I wanted the member to give more information:
void Foo::bar() {
char adieu[128];
int err = SomeAPIRoutine(...);
if (err != SUCCESS) {
std::strcpy(adieu,"In Foo::bar... ");
std::strcat(adieu,LibErrString(err));
throw MyExcept((const char*)adieu);
}
// otherwise...
}
However, when SomeAPIRoutine
returns an error, the what()
string returned by the exception contains only garbage. It occurred to me that the problem could be due to adieu
going out of scope once the throw
is called. I changed the code by moving adieu
out of the member definition and making it an attribute of the class Foo
. After this, the whole thing worked perfectly: a try-call block around a call to Foo::bar
that catches an exception has the correct (expanded) string in what()
.
Finally, my question: what exactly is popped off the stack (in sequence) when the exception is thrown in the if-block when the stack "unwinds?" As I mentioned above, I'm a mathematician, not a programmer. I could use a really lucid explanation of what goes onto the stack (in sequence) when this C++ gets converted into running machine code.
© Programmers or respective owner