标签云

微信群

扫码加入我们

WeChat QR Code


A chicken or the egg problem from the world of software... eternally debatable. :)

2018年09月25日59分37秒

Sorry about that, but hopefully having a variety of opinions will help people (myself included) choose appropriately.

2018年09月26日59分37秒

Yeah, BUT regarding your first example, that could be easily written as: if( !doSomething() ) { puts( "ERROR - doSomething failed" ) ; return ; // or react to failure of doSomething } if( !doSomethingElse() ) { // react to failure of doSomethingElse() }

2018年09月25日59分37秒

Why not... But then, I still find doSomething(); doSomethingElse(); ... better because if I need to add if/while/etc. statements for normal execution purposes, I don't want them mixed with if/while/etc. statements added for exceptional purposes... And as the real rule about using exceptions is to throw, not to catch, the try/catch statements usually are not invasive.

2018年09月25日59分37秒

Your first point shows what the problem with exceptions is. Your control flow gets weird and is seperated from the actual problem. It is replacing some levels of identation by a cascade of catches. I would use both, return codes (or return objects with heavy information) for possible errors and exceptions for things which are not expected.

2018年09月26日59分37秒

Peter Weber : It is not weird. It is separated from the actual problem because it is not part of the normal execution flow. It is an exceptional execution. And then, again, the point about exception is, in case of exceptional error, to throw often, and catch rarely, if ever. So the catch blocks rarely even appears in the code.

2018年09月25日59分37秒

The example in this kind of debate are very simplistic. Usually, "doSomething()" or "doSomethingElse()" actually perform something, like changing a state of some object. The exception code does not guarantee returning the object to the previous state and even less when the catch is very far from the throw... As an example, imagine doSomething is called twice, and increment a counter before throwing. How do you know when catching the exception that you should decrement once or twice? In general, writing exception safe code for anything that's not a toy example is very hard (impossible ?).

2018年09月25日59分37秒

+1 for very simple way to go. Atleast Its short enough so that I can read it very quickly. :-)

2018年09月25日59分37秒

I also prefer this way. Keeps code clean and expressive.

2018年09月25日59分37秒

"Exceptions are used solely for things that I'm NOT expecting." If you are not expecting them, then why do or how can you use them?

2018年09月26日59分37秒

Just because I'm not expecting it to happen, does not mean that I can't see how it could. I expect my SQL Server to be turned on and responding. But I still code my expectations so that I can fail gracefully if an unexpected downtime is occurring.

2018年09月26日59分37秒

Remember that using exceptions makes program analysis harder.

2018年09月25日59分37秒

The linked blog post is more about look before you leap (checks) vs. easier to ask forgiveness than permission (exceptions or return codes). I've replied there with my thoughts about that issue (hint: TOCTTOU). But this question is about a different issue, namely under what conditions to use a language's exception mechanism rather than returning a value with special properties.

2018年09月25日59分37秒

I completely agree. It seems I've learned a thing or two in the past nine years ;)

2018年09月26日59分37秒

Wouldn't it be slightly more correct to use assertions for contracts? If the contract is broken, there's nothing to save you.

2018年09月25日59分37秒

Exceptions are extremely expensive. They have to walk the stack to find potential exception handlers. This stack walk is not cheap. If a stack trace is built, it's even more expensive, because then the entire stack must be parsed.

2018年09月25日59分37秒

I'm surprised that compilers can't determine where the exception will be caught at least some of the time. Plus, the fact that an exception alters the flow of code makes it easier to identify exactly where an error occurs, in my opinion, makes up for a performance penalty.

1970年01月01日00分03秒

Call stacks can get extremely complex at runtime, and compilers generally don't do that kind of analysis. Even if they did, you'd still have to walk the stack to get a trace. You'd also still have to unwind the stack to deal with finally blocks and destructors for stack-allocated objects.

2018年09月25日59分37秒

I do agree that the debugging benefits of exceptions often make up for the performance costs, though.

2018年09月26日59分37秒

Derak Park, exception are expensive when they happen. This is the reason they should not be overused. But when they don't happen, they cost virtually nothing.

2018年09月25日59分37秒

Second example is misleading. Supposedly wrong way is wrong because os.path.rmdir code is designed to throw exception. Correct implementation in return code flow would be 'if rmdir(...)==FAILED: pass'

2018年09月26日59分37秒

COM wad designed to be usable by languages that don't support exceptions.

2018年09月25日59分37秒

That is a good point. It makes sense to deal with error codes for scripting languages. At least VB6 hides error code details well with encapsulating them in the Err object, which somewhat helps in cleaner code.

2018年09月26日59分37秒

I disagree: VB6 only logs the last error. Combined with the infamous "on error resume next", you'll miss the source of your problem altogether, by the time you see it. Note that this is the basis of error handling in Win32 APII (see GetLastError function)

2018年09月25日59分37秒

It will be strange if an object has .Close() but has no .Dispose()

2018年09月26日59分37秒

I'm only using Close() as an example. Feel free to think of it as something else. As I state; the using pattern should be used (doh!) if available. This of course implies that the class implements IDisposable and as such you could call Dispose.

1970年01月01日00分03秒

You're misinterpreting it. What they meant was "if your program throws exceptions in its normal flows, it's wrong". In other words "only use exceptions for exceptional things".

2018年09月25日59分37秒

At least in C/C++ and gcc you can give a function an attribute that will generate a warning when its return value is ignored.

2018年09月25日59分37秒

phjr: While I disagree with the "return error code" pattern, your comment should perhaps become a full answer. I find it interesting enough. At the very least, it did give me an useful information.

2018年09月26日59分37秒

This is what the <code>finally</code> statement is for. But, alas, it is not in the C++ standard...

2018年09月26日59分37秒

In C++ you should stick to the rule of thumb "Acquire resources in construcotor and release them in destrucotor. For this particular case auto_ptr will do just prefectly.

2018年09月25日59分37秒

Thomas, you're wrong. C++ has not finally because it does not need it. It has RAII instead. The solution of Serge is one solution using RAII.

2018年09月25日59分37秒

Robert, use Serge's solution, and you'll find your problem going away. Now, if you write more try/catches than throws, then (by judging your comment) perhaps you have a problem in your code. Of course, using catch(...) without a re-throw is usually bad, as it hides the error to better ignore it.

2018年09月25日59分37秒

There is no reason while you could not use an exception when you do l10n/i18n. Exceptions can contain localised information as well.

2018年09月26日59分37秒