Google's Go & Exceptions
dsimcha
dsimcha at yahoo.com
Tue Jan 26 09:11:30 PST 2010
== Quote from Justin Johansson (no at spam.com)'s article
> dsimcha wrote:
> >
> > Multiple return values are a horrible substitute for exceptions, because they
> > require the programmer to explicitly check the return value. (When's the last
> > time you checked the return value of printf, or even malloc?) IMHO the best thing
> > about exceptions is that they provide a sane default for error handling: If you
> > don't handle them then you've effectively asserted that they can't happen in your
> > situation. If this "assertion" fails, then our program fails fast and with an
> > error message that massively narrows down where the problem is. I flat-out refuse
> > to program in a language where the default is for errors to be ignored and I have
> > to constantly write explicit error-checking boilerplate even if I don't care about
> > handling the error.
> Well, back in C++ land, as an occasional alternative to using
> exceptions, I use a templated "checked_value" structure for returning an
> error code / function result pair.
> The C++ templated structure is shown below. A function returning
> a "checked_value" uses the first constructor form to return a
> valid result and the second form to return an erroneous result
> (using an enum to designate the error condition).
> If client code tries to access the value (via the
> overloaded cast operator, or you could have a getter
> function for the value instead), and an error is in effect
> that you didn't check for, then shit (an assert or other
> severity) happens.
> I'm sure there will be lots of religious comments about
> this idiom, but it works well for me by forcing a
> check for an error result before otherwise using the
> return value. Of course, this idiom only works if the
> function in question "returns something", a value, that
> the client code would by necessity have to use. It wouldn't
> (and couldn't) work if ValueType is "void".
> In the exceptional case (pun intended) of functions returning
> void, one may have to resort to throwing an exception instead
> to signal an error.
> So to counter the dsimcha's point, my solution does
> not assume a default situation of ignoring errors. The thrust
> of my argument is that exceptions are not an all-or-nothing
> approach in sane dealing in errors.
> template <typename ValueType>
> struct checked_value
> {
> public:
> checked_value( ValueType value)
> : _value( value),
> _rcode( RC_OK)
> {}
> checked_value( resultCode_t rcode)
> : _value( ValueType::PROP_INIT),
> _rcode( rcode)
> {}
> operator ValueType() const
> {
> // The value should not be accessible if the function failed.
> // Choose your poison with either assert or something
> // more severe in release compile if you don't like asserts
> // being preprocessed out.
> assert(!failed());
> return _value;
> }
> int failed() const
> {
> return (_rcode < RC_OK);
> }
> resultCode rcode() const
> {
> return _rcode;
> }
> private:
> ValueType const _value;
> ResultCode const _rcode;
> };
> Cheers
> Justin Johansson
Nice. This is probably a good idea in situations where it **always** makes sense
for the immediate caller to handle the error. Only problem is that Go! doesn't
have asserts either.
More information about the Digitalmars-d
mailing list