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