Are C++ `try`/`catch` blocks the same as other blocks, regarding RAII?
Asked Answered
N

3

5

OK so if I am using a RAII idiom to manage some context attribute*, will it work as I expect if I use it nakedly in at the start of a try block?

In other words, if I have this:

struct raii {
    raii() {
        std::cout << "Scope init"
                  << std::endl; }
    ~raii() {
        std::cout << "Scope exit"
                  << std::endl; }
};

… and I am successfully using it like this:

{
    raii do_the_raii_thing;
    stuff_expecting_raii_context();
    /* … */
}

… will the RAII instance work the same way if I do this:

try {
    raii do_the_raii_thing;
    stuff_expecting_raii_context_that_might_throw();
    /* … */
} catch (std::exception const&) {
    /* … */
}

This is probably a dumb question, but I want to check my own sanity on this – I am fuzzy on the subtleties of noexcept guarantees, and other exception-related minutiae – so pardon my naíveté


[*] for those curious, it’s the Python C-API’s nefarious GIL (global interpreter lock) that I am managing with RAII, in my specific case

Nosy answered 20/1, 2016 at 18:23 Comment(2)
Huh, that sounds like it does involve exceptions (or at least that it can) – but I take it you are referring to what this question explains: https://mcmap.net/q/24807/-does-c-support-39-finally-39-blocks-and-what-39-s-this-39-raii-39-i-keep-hearing-about/298171 … yes?Nosy
Oops, the comment I was replying to has vanished!Nosy
V
3

"… will the RAII instance work the same way if I do this: ..."

Sure they will. The RAII instance will go out of scope and the destructors are called before the catch, if an exception is thrown.

Also this will work for any upper levels, that are calling your function if you just throw and there aren't any try/catch blocks. That's called stack unwinding.

Veto answered 20/1, 2016 at 18:28 Comment(0)
V
5

Yes, it will do exactly what you want: First release the RAII resource and then process the exception block.

Viceregent answered 20/1, 2016 at 18:26 Comment(0)
V
3

"… will the RAII instance work the same way if I do this: ..."

Sure they will. The RAII instance will go out of scope and the destructors are called before the catch, if an exception is thrown.

Also this will work for any upper levels, that are calling your function if you just throw and there aren't any try/catch blocks. That's called stack unwinding.

Veto answered 20/1, 2016 at 18:28 Comment(0)
V
2

Yes, this is specified in the Standard:

15.2 Constructors and destructors [except.ctor]

2 The destructor is invoked for each automatic object of class type constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.

Vase answered 20/1, 2016 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.