Boost logo

Boost :

Subject: Re: [boost] [system][filesystem v3] Questionabout error_codearguments
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2009-11-02 13:09:34


Domagoj Saric wrote:
> >"Stewart, Robert" <Robert.Stewart_at_[hidden]> wrote in message
> >news:DF2E67F3D097004694C8428C70A3FD69046F26151F_at_msgbal516.ds.
> susq.com...
> > Domagoj Saric wrote:
> >> ..._only_ if you save the returned object into a local scoped
> >> variable _and_ do
> >> not inspect it can the issues of "library after throw" and
> >> "abort on exception
> >> in destructor during unwind" come into play...
> >
> > The complexity of this magical behavior
>
> did you have anything other in mind (besides the issues below)?

Not really. I was just noting that it seemed, to that point, a little hard to describe. Later when I tried, I found the description rather straightforward.

> > From a debugging perspective, the exception will be thrown
> > at the wrong point.
> ...
> > the problem with throwing in the caller rather than at the
> > point of error
>
> i'd say the 'debugging perspective' is here actually in the
> 'eye of the
> beholder' (i.e. up to the user to decide...in the sense that
> a function/library that uses the 'smart_error<>'
> approach has automatically given up the decision on what
> constitutes an
> exceptional situation/error/state and left that up to the
> user...and the

I think this is reasonable. The caller already decided to get a populated error_code rather than exceptions, so the source of the error isn't so important at that point. However, miscoded applications do get into production and it's awfully nice to get information about the real error -- not the, "Hey, stupid! You forgot to check for errors here" error -- to help diagnose the production problem.

> - the debugger can be instructed to break at points of smart_error<>
> construction when the status_code with which it is
> constructed is different from some "error_success" value...

Yes, though of course conditional breakpoints are horribly slow in many debuggers.

> - the function in question can save the __FILE__ and __LINE__
> information into the returned smart_error<> object

Yes. That's part of what I was alluding to above.

> - the particular "smart_error<>" class can be "instructed" to
> assert or call

I already mentioned asserting before throwing, so I agree with this.

> _CrtDbgBreak when constructed with a non-success "actual_error" (when
> debugging)...

That's usually part of asserting on Windows as I recall.

> > the overhead of checking to see whether to throw at each call site,
>
> there are ways that this can be minimized (or in some cases
> eliminated):
> - move the exception object construction and the throw
> statement into a
> separate (preferably nontemplated) function marked as noninline

The conditional logic is not affected by that, which I already assumed when I made the statement you quoted.

> - now we are left with an { if (!inspected && !succeded)
> do_throw() } which
> would/could probably translate to 5-6 cisc instructions

That is more than zero instructions, even if your estimate is accurate. Besides, those instructions are conditionals which, if they are not guessed properly, will stall a highly pipelined CPU's instruction cache.

> - if the returned error object is imediately inspected after
> the function
> returns (as is the intended use) it is 'plain obvious' to the
> compiler that
> those "remaining instructions" are redundant and would be
> removed completely...

What appears obvious to a human is not always so to an optimizer. You must prove that assertion by testing.

[snip more optimization thoughts]

> > and the danger of throwing in the destructor during stack unwinding,
>
> we seem to be "running in circles"...(afaik) there is no such
> danger for temporary objects...

Of course there is:

   error_code error;
   f(error);
   do_something_that_might_throw();
   if (error)
   {
      deal_with_error();
   }

If do_something_that_might_throw() throws an exception, error will not have been checked for errors. ~error_code() might detect an uncaught exception and avoid rethrowing, but there are other scenarios that complicate that.

> > makes overloading each affected function a pleasant alternative.
>
> sorry i still don't see either of the presented options as a
> 'clear win alternative'...
>
> and what exactly do you mean under "affected function"?

Each function that might throw or use error_codes to report errors can use the proposed interface (Beman's original query) or can be overloaded. Given the complexity of what has been suggested for error_code to complain should its error state not be inspected and the variability of its making that complaint, means that simply overloading each such function is trivial by comparison. The semantics of overloading are well understood; nothing new need be invented.

_____
Rob Stewart robert.stewart_at_[hidden]
Software Engineer, Core Software using std::disclaimer;
Susquehanna International Group, LLP http://www.sig.com

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk