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

fish2000
  • 4,289
  • 2
  • 37
  • 76
  • 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: http://stackoverflow.com/q/161177/298171 … yes? – fish2000 Jan 20 '16 at 18:45
  • Oops, the comment I was replying to has vanished! – fish2000 Jan 20 '16 at 18:45

3 Answers3

5

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

Mark B
  • 95,107
  • 10
  • 109
  • 188
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.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
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.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304