开发者

Throwing non-const temporaries by reference

开发者 https://www.devze.com 2022-12-20 20:04 出处:网络
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?

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() {开发者_如何学Python 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

throw;

instead of

throw e;

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

e.app("1"); 

call (and other calls to app) since the parameter is non-const reference. Change the app declaration to either

void app(const string& t) { where += t; }  // <- either this
void app(string t) { where += t; }         // <- or this

for 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消