Is there any problem with throwing an object constructed on the stack in a try-block by non-const reference, catching it and modifying it, then throwing it by reference to another catch block?
Below is a short example of what I’m refering to.
struct EC {
EC(string msg) { what = msg; }
string where;
string what;
void app(string& t) { where += t; }
string get() { return what; }
};
try {
try {
try {
EC error("Test");
throw error;
}
catch (EC& e) {
e.app("1");
throw e;
}
}
catch (EC& e) {
e.app("2");
throw e;
}
}
catch (EC& e) {
e.app("3");
cout << e.where << endl;
cout << e.get() << endl;
}
Is it possible that this could cause e.what to contain junk, but e.where to remain intact? For example:
e.where is “123”
e.get() returns a lot of garbage data, until it happens to hit a null byte.
There’s no such thing as “throwing by reference”. It is simply impossible. There’s no syntax for that. Every time you try to “throw a reference”, a copy of the referenced object is actually thrown. Needless to say, there are no attempts to throw by reference in your code.
It is possible to catch a previously thrown exception by reference (even by a non-const one) and modify the temporary exception object through it. It will work. In fact, you can re-throw the now-modified existing exception object instead of creating a new one. I.e. you can just do
instead of
in your catch clauses and still get the correctly behaving code, i.e. the original object (with modifications) will continue its flight throgh the handler hierarchy.
However, your code is ill-formed at the
call (and other calls to
app) since the parameter is non-const reference. Change theappdeclaration to eitherfor it to compile.
Otherwise, you code should work fine. You are not supposed to get any garbage from
get(). If you do, it must be either a problem with your compiler or with your code that you don’t show.