|
Boost : |
Subject: Re: [boost] D-style scope guards?
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-03-07 17:01:07
On Sun, Mar 6, 2011 at 1:54 PM, Sebastian Redl
<sebastian.redl_at_[hidden]> wrote:
>
> On 06.03.2011, at 16:05, Lorenzo Caminiti wrote:
>
>> Shall I ignore this case and require main() to always catch for the
>> C++ emulations of D-style scope guards to work?
>
> I don't think you have a choice. You *cannot* guarantee code execution upon an uncaught exception, at least not portably.
I see. Then I would simply declare an `error` local variable and add
an extra instruction to set it before throwing:
#include <boost/local/exit.hpp>
#include <iostream>
#include <stdexcept>
void f() {
bool error = false; // No error to start with.
BOOST_LOCAL_EXIT( (void) ) { // Smae as D's `scope(exit)`.
std::cout << "exit" << std::endl;
} BOOST_LOCAL_EXIT_END
BOOST_LOCAL_EXIT( (const bind& error) ) { // Same as D's `scope(success)`.
if (!error) std::cout << "success" << std::endl;
} BOOST_LOCAL_EXIT_END
BOOST_LOCAL_EXIT( (const bind& error) ) { // Same as D's `scope(failure)`.
if (error) std::cout << "failure" << std::endl;
} BOOST_LOCAL_EXIT_END
error = true; throw std::runtime_error("some error"); // Must set error.
}
int main() {
// Program cannot terminate with uncaught exception (otherwise local exits
// code is not guaranteed to be executed).
try {
f();
return 0;
} catch(...) {
return -1;
}
}
And similarly for error numbers instead of exceptions:
#include <boost/local/exit.hpp>
#include <iostream>
int f() {
int error = 0; // No error to start with.
BOOST_LOCAL_EXIT( (void) ) { // Same as D's `scope(exit)`.
std::cout << "exit" << std::endl;
} BOOST_LOCAL_EXIT_END
BOOST_LOCAL_EXIT( (const bind& error) ) { // Sane as D's `scope(success)`.
if (!error) std::cout << "success" << std::endl;
} BOOST_LOCAL_EXIT_END
BOOST_LOCAL_EXIT( (const bind& error) ) { // Same as D's `scope(failure)`.
if (error) std::cout << "failure" << std::endl;
} BOOST_LOCAL_EXIT_END
return error = -1; // Must set error.
}
int main() {
return f();
}
IMO, this is a clean and simple way to provide D-style scope guards.
-- Lorenzo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk