3 ms·
It's also useful for other purposes. http://www.reddit.com/r/cpp/comments/1ygcay/rarely_known_c_constructs_part_1_function_try/cfktzed http://www.reddit.com/r/
by nikbackm 13y ago
It's also useful for other purposes.
http://www.reddit.com/r/cpp/comments/1ygcay/rarely_known_c_constructs_part_1_function_try/cfktzed http://www.reddit.com/r/cpp/comments/1ygcay/rarely_known_c_c...
These days all resources should be wrapped in some kind of manager class like std::unique_ptr so there's really no need to use function try-blocks for that.
http://www.gotw.ca/gotw/066.htm http://www.gotw.ca/gotw/066.htm
- deleted 13y ago[deleted]
- nly 13y agounique_ptr/shared_ptr don't make a difference with regard to whether or not you need to use function-try blocks. function-try blocks are about whether the exception leaves the constructor, not whether the exception will result in destructors being called. For cleanup of constructed members when an exception is thrown in the ctor init-list it is required that you're in a try block somewhere up the stack. Observe: https://ideone.com/DYthrB https://ideone.com/DYthrB #include <iostream> #include <memory> struct Foo { int x_; Foo (int const x): x_(x) { if (x == 1) { throw x; } } ~Foo() { std::cerr << "foo_" << x_ << " destroyed" << std::endl; } }; struct Bar { std::shared_ptr<Foo> foo_0; std::shared_ptr<Foo> foo_1; std::shared_ptr<Foo> foo_2; Bar(): foo_0 (std::make_shared<Foo>(0)), foo_1 (std::make_shared<Foo>(1)), foo_2 (std::make_shared<Foo>(2)) { } ~Bar() { std::cerr << "Bar destroyed" << std::endl; } }; void xul() { Bar bar; } int main() { try { xul(); } catch (...) { return EXIT_FAILURE; } } Outputs: foo_0 destroyed foo_0 was destroyed here even though Bars destructor was never called Change main to: int main() { xul(); } Outputs nothing. foo_1 doesn't leak memory (it's freed by the shared_ptr constructor when Foos constructor throws) but foo_0 leaks because no shared_ptr destructors are ever called. This doesn't matter so much if you're just allocating memory (if you don't catch somewhere you're going to terminate anyway), but it could matter if Foo were a lock file or some other persistent system resource that can outlive the process, or another service somewhere is waiting for a message on a timeout. The alternative to relying on there being a try{} block somewhere up the stack is to add a function-try block on Bars constructor. tl;dr: member destructors aren't called if you throw from a constructor init list, function-try blocks fix that.