::std sometimes needed, sometimes not

M

Marcin Vorbrodt

Exactly. Macros are not ('assert' is a macro) in a namespace.
They cannot be, since they're merely text substitutions.


It's fine.

-MIke

Thanks a lot! Makes sense.

Martin.
 
J

Jerry Coffin

[email protected] says... said:
Heh heh. So am I, but I hope no one thinks I'm an expert.

No insult intended, but thinking about it a moment, that particular book
probably was a bad choice, and I apologize for mentioning it -- not
because I think it's a bad book, but the way in which I mentioned it
could (easily) be seen as self-serving, which I honestly didn't intend.

That aside, I think James Kanze is a respectable (and respected) C++
programmer with a tremendous amount of knowledge; while he's human, and
therefore may be wrong at times, dismissing his opinion without careful
consideration is usually a serious mistake, at least IMO.
 
L

llewelly

Kevin Goodsell said:
Gianni said:
Kevin said:
- You definitely do NOT want to throw an exception in case of a
contract violation. It is very, very rare, if ever, that this is
correct. The program is incorrect, and you abort.

The fact that every function can potentially throw an exception
makes writing exception safe code pratically impossible.

A lot of people seem to want exceptions anyway:). To keep them
happy, I would suggest some sort of callback, which the user can
replace. By default, the code should abort. If the user replaces
it with something which will throw, his code probably will not work
when the exception occurs. But since that's what he wanted...

This sounds like someone who doesn't understand exceptions to me.
OK - time for some friendly debate.
I'll state that I use exceptions very rarely and hardly ever in
production code.
I actually agree the the quote 100% because I have done exactly that
and found that it is a very acceptable paradigm for developing solid
and easily maintainable code.

I don't think that library code should ever unilaterally abort the
program. Besides that, doing so causes objects to go undestructed,
leading to resource leaks (sure, most modern desktop systems clean up
when the process terminates, but you can't count on that in portable
code).

I don't understand why you would prefer aborting to throwing an
exception anyway. What's the worst case for throwing an exception?
It's not caught, and the program aborts. So by aborting instead of
throwing, you're ensuring that you always get the worst case.
[snip]

A contract violation occurs when a programmer has made an error
in the design or implementation of the code. So the violation
proves the code is incorrect in some unknown manner. Throwing an
exception results in the execution of cleanup code. However, the
code is known to be incorrect, but the nature of the error isn't
known precisely, so one can't know if it is safe to execute the
cleanup code; there may be some device-controlling object whose
destructor is supposed to shutdown the device, but misbehaves
terribly if the object is overwritten by e.g. memcpy with wrong
parameters. Terminating is not necessarily the worst case when
throwing an exception. Thus the abort.

There's also a conceptual mismatch. Exceptions have acompanying
features - try, catch(), destructors, - for responding to the
exception, and carrying on with the program's job. However, if
the code is wrong, the proper response is to fix the code. How do
you put that in your catch block? In general, I don't think you
can, especially not in a language like C++ .

There's an exception safety issue. Any useful level of exception
safety must rely on a few non-throwing operations. Yet in
principle a programmer error can occur in any aperation. Few
people put asserts in every function, but there are no-throw
functions complex enough to need asserts. If you try agressively
to detect programmer errors, and throw exceptions when programmer
errors are detected, I think you'll find it much more difficult,
to make your code exception safe.

Finally, there's an environment support issue. On many
implementations, throwing an exception unwinds the stack,
destroying any informantion about where the error was
detected. Typically, no stack trace is printed when the program
terminate()s due to an uncaught exception. By contrast, abort()
often leaves a core image behind, which can be loaded into a
debugger and inspected.

This isn't an argument for never using exceptions; I believe
exceptions are for conditions the code 'understands', and is
designed to repsond to. abort() is for conditions that can only
occur if some programmer has written incorrect code.
 
G

Gavin Deane

Kevin Goodsell said:
A few ideas come to mind, but none is anywhere near perfect. You could
abort or throw depending on a build setting, for example. But if you
test with abort and ship with throw then you don't even know if the
catching code is in place or doing anything sensible. You'd have to test
with throw, and it could be covered up.

That's exactly what I do and I don't see any problem. I am working on
small scale stuff though, with a build time measaured in a few minutes
at most, not several hours. It is very easy for me to do a release
build during testing to check that the catching code does what it is
supposed to (which isn't much - write the error message to a file and
exit the program).

GJD
 
J

Jerry Coffin

[ ... ]
For the record, I wasn't really considering the context of the quoted
message, just exception handling in general.

That explains a LOT. I certainly don't think James meant that comment
in general (i.e. that you should all exceptions would be better off as
abort()'s).

[ ... ]
But looking at just the contract violation case, obviously it's a bug
that should be fixed. But at least some bugs always make it into the
final product. Terminating the program when a problem is found is not a
very useful behavior from the perspective of the user of the
application. In fact, I don't think most users would be very happy with
that.

I quite agree, and James basically allowed for the same possibility:
handle the situation with a call-back function. The default call-back
abort()'s, but the user of the class can register a different one that
does what he deems appropriate -- probably throw some exception.

[ ... ]
Yes, I agree that this is bad. But it only happens if you explicitly
ignore the exception.

Yes, but explicitly ignoring the exception (or handling it
inappropriately, if it inherits from an inappropriate base) is often
very easy to do.
This is not true from the user's perspective, though.

That depends on the user and the type of code involved. It's also
possible to install a default handler that attempts to sit in the middle
ground. Just for example, quite a few recent MS programs have a handler
that asks to email a bug report to them if an exception percolates out
far enough. Offhand, I don't know that they're using C++ exceptions for
this (it wouldn't surprise me if they use their own Structured Exception
Handling instead) but the idea is more or less independent of the
implementation.
Yes, I definitely agree that this is a problem. But one way to look at
it is that it's not really *your* problem. If you threw the exception,
you've done your part. If the caller ignores it, then they screwed up.
But this doesn't make any difference in many cases. If the program
breaks for the customer, you'll still be in trouble.

The point is that you really haven't "done your part." Exceptions are
intended to handle situations that are (or at least may be) recoverable.
Just for example, if a memory allocation fails, a program might attempt
to free up other memory that's caching various data, and then continue
with its job. Therefore, an exception works well.

Unless you have a system in which it at least MIGHT be possible to
recover from a contract violation, an exception is not an appropriate
way of dealing with the problem (an example would be if the program
responded to a contract violation by attempting to download an updated
version of the component that caused the problem).

[ ... ]
You could try to make an un-ignorable exception, maybe. Suppose your
exception object includes a 'handled' flag. On construction, this flag
is false. The catcher must set it to true. On destruction, if the flag
does not indicate that the exception was handled, the destructor aborts
the program. The problem is that it can still be ignored, it just takes
a little more effort (catch, set the flag, do nothing else).

I think we're mostly in agreement here -- ultimately, C++ doesn't
provide a single, obvious way that a contract violation _should_ always
be handled. I'm reasonably convinced that the usual exception mechanism
without any adornment (for lack of a better word) is rarely a good way
to handle it. The adornment you've given above might work nicely for
some situations, but I'm not at all sure that it's a universal solution
either.

That's not intended as a slam though: it may easily be that there simply
IS no universal solution to this problem, or at least that if there is
it's not a direct, simple and obvious one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top