The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Google says no to C++ exceptions

"We do not use C++ exceptions." Google C++ Style Guide:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exceptions

As a Java programmer coding his first game in C++, I find it rather odd that C++ programmers shun exceptions in practice (not only google, but lots of gaming programming libraries for instance). Why is that? This topic has been discussed before, and apparently performance (or lack thereof) is NOT a reason:

http://discuss.joelonsoftware.com/default.asp?design.4.484274.20
pastryman Send private email
Thursday, July 24, 2008
 
 
They give a pretty detailed explanation for their decision, on the page you linked to.
JW
Thursday, July 24, 2008
 
 
First reason seems to be they've got a lot of legacy code that DOESN'T use exceptions, and retro-fitting that code would be problematic.

Second reason seems to be that HOW, WHEN, and WHY to use exceptions is still evolving, and they don't have a complete policy for that.

Third reason is a size and performance concern, but that seems a fairly minor consideration.

Like many facilities new with C++, good engineering approaches toward using them are still evolving.
AllanL5
Thursday, July 24, 2008
 
 
In my view "the discussion is still evolving" is a bit silly. It's been well over a decade since exceptions have been introduced. There are no real surprises left here.

For all their flaws, exceptions are a heck of a lot better than error return codes. The vast majority of code I've seen that uses error return codes simply doesn't check it. That's just begging for problems...
Gili Send private email
Thursday, July 24, 2008
 
 
> retro-fitting that code would be problematic

That reminds me of the snowball effect that occurs when you start writing const-correct code.
dev1
Thursday, July 24, 2008
 
 
> snowball effect that occurs when you start writing const-correct code

That's a trivial change though: adding 'const' to the declaration of a method doesn't change its behaviour (provided that it was in fact logically-const to begin with).

I wonder what Google's style-guide says about out-of-memory conditions: that's the most useful use case for C++ exceptions.
Christopher Wells Send private email
Thursday, July 24, 2008
 
 
It seems to me that languages that have exceptions 'baked in', such as Delphi and C# are much friendlier to use exception wise that languages such as C++ where exceptions are tacked on later. The fact that using exceptions in C++ is even optional should be a hint about their status within the language.
Craig Send private email
Thursday, July 24, 2008
 
 
>> I wonder what Google's style-guide says about out-of-memory conditions: that's the most useful use case for C++ exceptions.

I found nothing. My overall impression is that this google guide doesn't add much to Effective C++, if any.
Phil
Friday, July 25, 2008
 
 
I don't much like structured exception handling because it makes code harder to follow when abused (as the Java class libraries abuse it). But it's especially nasty in C++ because it hardly ever works when you need it. It uses the setjmp/longjmp mechanism underneath I think. Whenever something goes bad in C++ the stack will likely be trashed. And when the stack is trashed setjmp/longjmp won't work.
Rowland
Friday, July 25, 2008
 
 
>> That's a trivial change though: adding 'const' to the declaration of a method doesn't change its behaviour (provided that it was in fact logically-const to begin with).

Straying a bit off-topic - the problem you run into when you add const to a 'logically const' method is that now all the functions/methods you call with the newly const parameter or object must also be marked const - and so on down the call chain.

This quickly turns into a real pain for a whole lot of code if the code base was not completely 'const correct' from the get go. Or you'll find yourself punting and doing a bunch of const_casts to keep the compiler happy.
mwb
Friday, July 25, 2008
 
 
The summary from the link above says:

- Do not use exceptions for normal program flow.
- Exception handling does have a performance cost
- Not always measurable
- Cost really depends on usage
- Frequently similar to what correct code would be, without EH[at least in VC8]
- Do not use exceptions for normal program flow.
- C++ is cheaper than SEH for cleanup in VC8.
- Use common sense, and knowledge of your team’s strengths/weaknesses if you’re mandating SEH/C++ EH/No EH
  - New hires rarely know about SEH.
  - Source level readability & visibility of performance
- And finally, do not use exceptions for normal program flow.

Friday, July 25, 2008
 
 
> methods you call with the newly const parameter or object must also be marked const - and so on down the call chain

Yes, but 'marking as const' doesn't change the run-time behaviour of the program; whereas, if some subroutine or library decides that it would like to start throwing exceptions, *that* changes the program's run-time behaviour.
Christopher Wells Send private email
Friday, July 25, 2008
 
 
This got brought up before and here was my colorful reply.. hehe

"In reality, when you see documents that say "don't use exceptions" or "don't use RTTI", etc., etc. its because it is a large company that has a lot of terrible programmers.  It might also have brilliant programmers, but they are protecting against the lowest common denominator.

If you have small groups of excellent programmers, you don't make blanket statements like "don't use exceptions".  You enable your people to use the best tool.  Frankly return codes are crap.  What happens with them?  People don't check them.  At least something goes horribly wrong with an uncaught exception, something that will actually be found in proper testing.  Unchecked return codes, who knows.

If you are one of those who swears off certain features of C++, frankly, it is probably because you don't know how to properly use them, and you don't have the inclination to learn something new.  You have a linear line on the career calculus chart."
Spyplane Send private email
Friday, July 25, 2008
 
 
Spyplane: "Frankly return codes are crap.  What happens with them?  People don't check them.  At least something goes horribly wrong with an uncaught exception, something that will actually be found in proper testing.  Unchecked return codes, who knows."

I check return codes. Don't you?

Programmers who don't check error codes are crap.

In C++ I've had things go horribly wrong and the exception handling didn't do one damn thing for me because THE STACK WAS TRASHED.

Here's a middle ground. First have sig handers for REAL exception conditions such as stack overflows, bad references, arithmetic overflow.

For everything else let every thread instance have a status variable that holds all the information a structured exception in Java would. Set it when something goes wrong. Check it when it's convenient to do so so. Have an option such that the library call to set the error data can also log the error together with a stack trace. Use this option only on errors that may indicate bugs.

That and lots of ASSERTs to define the constraints on valid arguments. Have a second nonfatal form of ASSERT that logs the failure with a stack trace.
Rowland
Friday, July 25, 2008
 
 
Exceptions also don't propagate across processes and different machines, but return codes can. For distributed projects you really need to use return codes, I've found.
John
Friday, July 25, 2008
 
 
> THE STACK WAS TRASHED

That's a coding error (or, far less likely, a hardware fault): not an exception. Bad references, stack overflows, corrupt heap, etc., => "undefined" behaviour.

Ignoring the fact that exceptions may not work properly if there has been a coding error, exceptions are especially useful for handling insufficient-heap conditions, for example:

class B
{
};

class A
{
  B* b;
public:
  A()
  {
    b = new B();
  }
};

void test()
{
  A* a = new A();
}

If operator new doesn't throw an exception, how can test() know whether A::A() was able to allocate its b member? Instead, wouldn't you need to implement two-stage construction of classes which contain embedded pointers (including std::string for example) e.g. ...

  A* a = new A();
  if (!a || !a->is_constructed_ok())
  {
    //handle the oops
  }

... and/or ...

  A* a = new A();
  if (!a || !a->finish_construction())
  {
    //handle the oops
  }
Christopher Wells Send private email
Friday, July 25, 2008
 
 
It's weird that some people are trashing "return values", because "people don't check them", but proposing "exceptions" as a solution.

Because if you don't 'catch' all exceptions, you'll get the same crashing behavior unchecked return values give you.
AllanL5
Friday, July 25, 2008
 
 
> if you don't 'catch' all exceptions, you'll get the same crashing

You can write one exception handler high up in the call stack:

void run
{
  while(!shutdown)
  {
    try
    {
      do_stuff();
    }
    catch(std::bad_alloc&)
    {
      free_some_memory();
      //try again now that we have more memory
    }
  }
}

This is cleaner than using return codes, because all of the do_stuff() code doesn't need to test whether each operator new succeeded ... and if there were no C++ exceptions and if the do_stuff() code didn't notice a null pointer being returned then there'd be "undefined" behaviour.
Christopher Wells Send private email
Friday, July 25, 2008
 
 
Allen,

The difference b/w an unchecked return code and a uncaught exception is that the exception will force the crash and will be easy to find.  The return code might NOT crash the code and could be one of those bugs that lingers a long while and is hard to track down. 

I use return codes when necessary, but to outright say no to exceptions is foolish.
Spyplane Send private email
Friday, July 25, 2008
 
 
Dude, it's Google that's saying no, I'm not sure who you're trying to convince.
AllanL5
Friday, July 25, 2008
 
 
What I don't like about checked exceptions in Java:

1. I have method A which doesn't throw any checked exceptions.
2. I modify it so it does. Now I need to add "throws XXX" whenever it is called.
3. I modify it again so it doesn't. Now I get stuck with unnecessary "throws XXX" clauses.

Am I doing something wrong?
quant dev Send private email
Friday, July 25, 2008
 
 
Yes, by using Java.
use c++ plz
Friday, July 25, 2008
 
 
quant dev:
"Am I doing something wrong?"

You might be over-using checked exceptions.

You should only use a checked exception in cases where the programmer can reasonably be expected to recover from the exception (e.g., a file that doesn't exist). This usually means that some user-submitted value was no good, and you should prompt the user for a new value (or use a default fallback value).

Unchecked exceptions (subclasses of RuntimeException) should be used for whenever the programmer made an error (e.g., array index out of bounds, incorrect format specifier, out of memory, etc).

In some cases, it's not obvious where a piece of data is coming from. For example, a URL might be input by the user, but it might be constructed within the software. But the URL constructor throws a checked exception, in case of an illegal URL format.

In cases where I'm constructing the URL programmatically, I'll catch the checked exception, wrap it in a RuntimeException, and re-throw it.

I'll only propagate a checked exception up through the call hierarchy in cases where it's an actual recoverable exception (and NOT a programmer error), and where the exception handling should be written somewhere higher in the call hierarchy.
BenjiSmith Send private email
Friday, July 25, 2008
 
 
"You might be over-using checked exceptions."

Unfortunately, my company has a policy of not using unchecked exceptions. Programmer errors are supposed to be handled by asserts. However, we run our code with assert checking turned off, because it would fail in many places if we turned it on.

Yeah, it's a mess but it brings us loads of cash anyway ;-)
quant dev Send private email
Friday, July 25, 2008
 
 
>> You might be over-using checked exceptions.

checked exception has to be a design flaw of Java IMO. In a really app, you have to assume that any exception can happen anywhere and all exceptions must be caught. This is doable in an elegant way (maybe impossible in Java though with checked exceptions already built into J2SE). In my view, a good app should be able to catch an "out of memory" exception and prompt the user for further action. Unfortunately, most apps cannot pass such a test.
Phil
Friday, July 25, 2008
 
 
> a good app should be able to catch an "out of memory" exception and prompt the user for further action.

Things can get a bit tricky in such situations, the 'prompt the user for further action' may require some extra memory as well.
Yanic Inghelbrecht Send private email
Saturday, July 26, 2008
 
 
Funny thread. Now after Microsoft added exceptions to VB.NET, we are revalidating the usage of C++ exceptions. Exceptions (also C++ exceptions) as return codes has their place in the programming and should be used when approppriate. For those interested in C++, checkout Exceptional C++, and More exceptional C++ (I believe were the titles). Companies can always have policies and they even don't have to be defined by programmers.

C++ has a separate stack for exceptions, so the code stack is not damaged. I believe every C++ compiler vendor is free to define underhoods how will implement the exceptions (the standard must be obeyed).

Uh, I almost forgot:
DON'T USE C++ EXCEPTIONS!
Goran Burcevski Send private email
Saturday, July 26, 2008
 
 
"Companies can always have policies and they even don't have to be defined by programmers."

Ours was defined by senior devs. I will have to ask them about it...
quant dev Send private email
Saturday, July 26, 2008
 
 
Christopher Wells: "> THE STACK WAS TRASHED

That's a coding error (or, far less likely, a hardware fault): not an exception. Bad references, stack overflows, corrupt heap, etc., => "undefined" behaviour."

Yes, a coding error. BUT WHOSE?

And aren't nearly all legitimate exceptions the result of coding errors? Somebody mismanaged his pointers. Somebody divided by zero.

Good luck trying to find where the stack gets munged if it's in someone else's library that you can't compile from source.

One nice thing about Java is it doesn't let you OR ANYONE ELSE store non-scalar data on the stack. Slows down execution a bit but it's a price I'll gladly pay.

I've yet to find a case where C++ structured exception handling really paid off for me. It's little use except for debugging because by the time the exception kicks in irreparable damage has already been done to the .data segment. And it's no good for debugging in C++ because it just doesn't work properly.

I suppose it might be useful to catch allocation failures and try to clean up afterwards. But somehow I can always find a cleaner way to accomplish that than structured exception handling.

An exception that reports on a failed system call is a kluge. Better to return an error code. Better yet to use the middle-of-the-road scheme I described above.

The only other way structured exception handling could add robustness to a program is to catch divide by zero errors. And that's a poor second to not dividing by zero in the first place.
Rowland
Saturday, July 26, 2008
 
 
>> the 'prompt the user for further action' may require some extra memory as well.

Memory should be pre-allocated for recovery. Maybe recovery is not quite important for the client, but it is for the server to keep running.

>> Uh, I almost forgot:
DON'T USE C++ EXCEPTIONS!

I am curious how you handle the "out of memory" situation. always check the return value and use goto? I've seen code like that a lot and it is not pretty.

>> I suppose it might be useful to catch allocation failures and try to clean up afterwards. But somehow I can always find a cleaner way to accomplish that than structured exception handling.

Is this also cleaner than the standard EH in c++? And can you share with us your technique?
Phil
Saturday, July 26, 2008
 
 
> And aren't nearly all legitimate exceptions the result of coding errors? Somebody mismanaged his pointers.

They shouldn't be: somebody's mismanaging his pointers isn't "legitimate" ... it's 'illegal' from the point of view of the language.

Legitimate exceptions are more, maybe:

* Software is run in the wrong environment (e.g. out of memory, network disconnected, file write-protected, ...)

* Logical errors, which are legal from the point of view of the language but not of the software ... like, I don't know, the caller's not satisfying a http://en.wikipedia.org/wiki/Precondition

You may argue that 'wrong environment' errors should be handled via return codes.

I think that the most vital (perhaps the only vital) exception is bad_alloc ('thrown by new on allocation failure'), which is the O/S failing to satisfy the language.

The 'coding errors' you mentioned (e.g. mismanaging pointers) can only be handled by O/S exceptions or signals ... if you mis-use the language then the language can't protect you ... most of the 'safety' of C++ is at compile-time, not at run-time.
Christopher Wells Send private email
Sunday, July 27, 2008
 
 
The general problem here is one of cargo-cultism.

People pick up on things that Google does because Google can, and think that their use of them will make them Google.

Google can afford to not use exceptions, and they require (in some places) the performance that not doing so gives them.

Everyone else is not Google and not even Google-like.

Google can afford to hire really good engineers and then give them lots and lots of time to develop in so that they can be really conscientious and check all the return codes and to audit all the lines of code to make sure they are doing and do all the unit testing and then all the system testing and actually they can afford to ship broken stuff several times and weather the results. They have a basically unbounded hiring and development budget.

Most other people do not, and should not be attempting development which requires those resources. Your coding practices need to cope with not having enough time or people, and with requirements which change unexpectedly, in chaotic environments with bad testing, but the best you can do. It is highly likely that any single line of code you write will ship to the customer without being hit by a test and without being read by any developer past the one who wrote it.

Don't follow Google's ideas of what constitute good practices unless you also have the other things that make them work. And you almost certainly don't.
Katie Lucas
Sunday, July 27, 2008
 
 
Christopher Wells: "They shouldn't be: somebody's mismanaging his pointers isn't "legitimate" ... it's 'illegal' from the point of view of the language."

If it's REALLY illegal from the point of view of the language then the code won't compile in the first place.

The sad fact is that all sorts of things are legal in low level languages that are really not good ideas, and it's way too easy to do these things by accident. Adding features such as structured exception handling isn't going to help that. The proper solution is to use such languages sparingly and with great care.
Rowland
Sunday, July 27, 2008
 
 
Phil: "I am curious how you handle the "out of memory" situation. always check the return value and use goto? I've seen code like that a lot and it is not pretty."

No I don't use goto. I don't use structured exceptions either because they're even uglier than goto.

I've never run into a situation where an allocation failure couldn't be handled without recourse to either of these. At least not by me. I think it's because of my style of programming. I try to see all important series of events and write my code with them all in mind. I have a very event driven style. Programmers I consider inferior will code more procedurally. They write a core of reasonably structured code to handle the most pollyana-ish case where every operation succeeds perfectly. Then they tack on all sorts of bits almost as afterthoughts to try to handle when things go wrong. It's a band-aid approach and the band-aids accumulate and interfere with each other and obscure everything. I see this as a failure to think holistically.

Structured exception handling is a language facility to help make band-aids. I don't WANT band-aids.

Some much better techniques:

* Data protected by mutex.

* Idempotency wrappers.

* Deconstructors written to handle partially constructed data structures.

* ALWAYS zero a pointer when created, and after freed.

* NEVER have a pointer from one data structure into another independent data structure unless the first structure is something VERY temporary such as an iterator.
Rowland
Sunday, July 27, 2008
 
 
> If it's REALLY illegal from the point of view of the language then the code won't compile in the first place.

The compiler can't detect a coding error such as double-delete (borking the heap) at compile-time, and it's unfeasably expensive to detect it at run-time ... so all it can say is, "don't do that, it's unsupported."
Christopher Wells Send private email
Sunday, July 27, 2008
 
 
@Rowland

"Programmers I consider inferior will code more procedurally. They write a core of reasonably structured code to handle the most pollyana-ish case where every operation succeeds perfectly."

But it's cheaper that way. I write code to increase my employers profits, not to achieve holistic perfection.
quant dev Send private email
Sunday, July 27, 2008
 
 
I think what I love the most about this debate is the fact that people's belief in the performance penalties of exception handling is more solid than the pope's faith in Jesus, yet the same people will use languages with stop-the-world style garbage collection and not think twice about performance.

There may or may not be real and serious problems with exception handling, but there aren't many people here who I'ld trust to be able to explain any real issues that may exist.

Sunday, July 27, 2008
 
 
Rowland,

Thanks for listing some of the techniques you use. I do most of the things you do, including event driven style. But there are at least two things we do differently (let's forget goto):

1. The return error code. In a large project, function calling can be deep. So all the functions must at least return one value, and error checking has to be done at every level. The value of throwing exceptions is thus to check certain errors at a certain level. Actually I think being able to check one type of exception, like out of memory, at one place, is quite elegant.

2. I imaging you avoid dynamically allocated memory as much as you can, and probably use copy constructor a lot, in a STL style. But you can't copy everything and large amount of data has to be shared between structures though pointers.
Phil
Sunday, July 27, 2008
 
 
>> But it's cheaper that way. I write code to increase my employers profits, not to achieve holistic perfection.

Actually, exception handling is an effort to achieve both.
Phil
Sunday, July 27, 2008
 
 
What I do in practice is:

1) I don't throw exceptions in my own code (I never find myself in the need to do so; if one day I do, then I will).

2) Some functions may succeed or fail. Then I return a code. If you don't check it, don't call my code. It's your problem. If I can read the contract of a function and respect it, you can, too. If you can't read it then you don't know what my function does - so why would you call it? because it has a fancy name?

3) I catch any documented exceptions in library functions I call (and I understand some of them might be justified; e.g. querying values in a database which is accessed through a connection which is not working at this moment).

4) If an out of memory situation occurs, tough luck. You'll get an unhandled exception in real time. Will you survive it? I survive the crashes of Internet Explorer, Microsoft Office, Windows Explorer... every other day. And millions have been poured into these projects. And they crash. So if we run out of memory, there you have it: an out of memory exception and the program will be terminated.
Daniel_DL Send private email
Monday, July 28, 2008
 
 
"So if we run out of memory, there you have it: an out of memory exception and the program will be terminated."

Good thing you were not involved with the life support system code for the Space Shuttle.
anony
Monday, July 28, 2008
 
 
So how does the life support system code for the Space Shuttle look like?

1. Pre-allocate or stack-allocate everything?
2. Diligently check return code every time?
3. Still no Exception?
Phil
Monday, July 28, 2008
 
 
>> Good thing you were not involved with the life support system code for the Space Shuttle.

Sure, but not all coders or code are or need to be.  My car isn't engineered to Space Shuttle specs - should I refuse to drive in it?
mwb
Monday, July 28, 2008
 
 
I think the solution is obvious.

As we're all clearly as dumb as a bag of rocks we should all commit suicide, and Daniel the Genius Superprogrammer will write all our code for us over the weekend.

Given that anyone who ever makes a mistake apparantly deserves to have crappy software I can't imagine He (and he most definately deserves the capital letter for His greatness is obvious to anyone) would ever make a mistake, and thus we should just get out of His way and let Him code.

(Or we could show some consideration and possibly even skip the arrogance, but that's no fun.)

Monday, July 28, 2008
 
 
In my experience it depends on what I was doing

Satellite Experiment - verboten
OS Kernel - verboten, not possible
OS APIs - verboten,
NLP - common
Data Cruncher - common
Financial Modeling - permitted
Financial Transactional - verboten

The determining factor was really cross language / cross library dependencies.  I have never professionally worked on a pure C++ project.
B
Tuesday, July 29, 2008
 
 
"Given that anyone who ever makes a mistake apparantly deserves to have crappy software"

(Skipping your tone)

Do you really infer that from what I wrote?
Daniel_DL Send private email
Tuesday, July 29, 2008
 
 
"Good thing you were not involved with the life support system code for the Space Shuttle."

Had I been, I would have adapted my policy.
Daniel_DL Send private email
Tuesday, July 29, 2008
 
 
Daniel_DL: "4) If an out of memory situation occurs, tough luck. You'll get an unhandled exception in real time. Will you survive it? I survive the crashes of Internet Explorer, Microsoft Office, Windows Explorer... every other day. And millions have been poured into these projects. And they crash. So if we run out of memory, there you have it: an out of memory exception and the program will be terminated."

From the code I've seen out there I'd say you're in the majority on this one. That doesn't make you right though.

Computing hardware resources are ALWAYS finite. What somebody wants from his computer can easily exceed the computer's ability. So the computer will disappoint him frequently due to running out of resources.

Given that this will happen frequently shouldn't we try to handle it as gracefully as possible? Shouldn't we at least attempt to fail softly and without damaging data?
Rowland
Tuesday, July 29, 2008
 
 
"So how does the life support system code for the Space Shuttle look like?

1. Pre-allocate or stack-allocate everything?
2. Diligently check return code every time?
3. Still no Exception? "

I've worked on life critical and mission critical software for aircraft (not the shuttle, but similar).  Exceptions are not used, but C++ is also not used at all.  Each line of code is reviewed and reviewed and reviewed.  I would say that a line of code from birth to release probably takes 30-50 times longer than the average software.  If you look at how many lines of code we had versus the time it took to get there, you would be astounded.  But again, this was a very unique circumstance.  Not every shop can take 6 months to roll from 6.2.x to 6.2.x+1.
Spyplane Send private email
Tuesday, July 29, 2008
 
 
"Had I been, I would have adapted my policy."

At least you're not set in your ways. <small grin>
anony
Tuesday, July 29, 2008
 
 
When I was learning C++ I read a book called Exceptional C++.  It was about how to write exception safe code.  You see it is hard to use exceptions safely in C++ because it is not a garbage collected language.  After reading Exceptional C++ I decided that learning exceptions simply would never be worth it.  Whatever minuscule benefit I get would be offset by the errors introduced by going through the trouble of making my code exception safe.
Tom
Tuesday, July 29, 2008
 
 
"Given that this will happen frequently"

I have _never_ been reported an out of memory situation from my software.

The "arrogance" some mentioned doesn't have its place in this thread. I've been reported quite a number of bugs from my code or my team's code. Bad pointers. Undefined values. Off-by-one mistakes. Infinite loops. Badly sized arrays. My point is just that none of them has ever been an out of memory unhandled exception. My second point is, I sincerely can't think or bother to spend time thinking of a nice recovery strategy for when an std::bad_alloc happens. What should I do? Sleep 500 ms and try again to allocate memory? Ask the user to please kill other processes? (But can I even create a new dialog box to ask him this, if there is no more free memory?)

In most desktop apps of the domains I worked in (not embedded, not the NASA, not the Chernobyl nuclear plant), if you're out of memory, this is not your lucky day, sorry. Everything will go wrong. Maybe you should reboot.

Just curious, but I've recently moved to .Net. From what I've seen, noone even gives a thought to what happens if there is not enough memory available when programming in C#. See:

string [] stringArray = new string [50];
int [] numbers = new int [100];

Do you handle at all the case when these new statements fail?
Daniel_DL Send private email
Tuesday, July 29, 2008
 
 
In c++, you can overload a global new and throw an exception there.

In c#, well, I ignored them or checked only big ones.
Phil
Tuesday, July 29, 2008
 
 
"In c++, you can overload a global new and throw an exception there."

I read about this in "Effective C++", but, well, you already have an exception globally thrown if you do nothing - std::bad_alloc. :)
Daniel_DL Send private email
Wednesday, July 30, 2008
 
 
"Whatever minuscule benefit I get would be offset by the errors introduced by going through the trouble of making my code exception safe."

Once you start using RAII, you'll find that you have fewer errors overall.  It's always easy to forget some cleanup code in your error branch.

I once had a huge library that was error code based that I wanted to convert to using exceptions.  I was able to replace the enumeration based error return code with an error class; it would detect whether the caller had checked the code, and throw an exception if there was an error condition that the caller ignored.
Mark Ransom Send private email
Wednesday, July 30, 2008
 
 
Daniel_DL: "My second point is, I sincerely can't think or bother to spend time thinking of a nice recovery strategy for when an std::bad_alloc happens. What should I do? Sleep 500 ms and try again to allocate memory? Ask the user to please kill other processes?"

Either of these would be better than doing nothing and also better than trying to handle with exceptions.

But here are some guiding principles to help find a nice recovery strategy:

* If at first you don't succeed and retrying is not an option, fail gracefully. Use transactions in your databases. All other file writes try to make them atomic. Do NOT damage data on the disk. Not ever.

* Always inform the user when and why you are failing and to what extent. Not a popup. I hate popups. A blinking status line is better. If nothing else avails a log entry will do.

* If on occasion you don't succeed, fail softly. Don't be brittle. Don't just crash under heavy load. Start refusing certain user or client requests that you can't perform at the moment but ALWAYS with a reason given. Keep the user in the loop and leave his options open. Think temporary partial failures, the software analogue of a power brownout.

* Always be prepared to free a partially built data structure.

* Have timeouts on your I/O wherever possible.
Rowland
Wednesday, July 30, 2008
 
 
>> Either of these would be better than doing nothing and also better than trying to handle with exceptions.

Exactly what's the logic for making this comparison?

>> But here are some guiding principles.

OK guidelines. Now do you use these string classes, like std::string, CString in MFC, etc? Exactly how do you handle the out of memory situation? We all know there is no return code to check.
Phil
Wednesday, July 30, 2008
 
 
"Whatever minuscule benefit I get would be offset by the errors introduced by going through the trouble of making my code exception safe."

Of course, whatever benefits you get from not using exceptions is also offset by the errors introduced by going through the trouble of making your code error-code safe.

Error handling is hard, and what a person is used to tends to be easier than anything new. But we're still talking about a language that doesn't even have garbage collection and somehow assuming that exception safety is harder than memory-leak safety. Hell, if your code isn't already exception safe then I'ld be shocked if you didn't leak memory.

While I like C++ I suspect that its debates like this that make the claim "using C++ is premature optimisation" seem sensible.

And talking of garbage collection, I bet more than a few of the "I hate exceptions" crowd will never be able to move away from C++ because C# may have garbage collection but if you don't write exception-safe code you'll tend to get some amusing bugs when you fail to clean up after yourself.

Wednesday, July 30, 2008
 
 
>>  It seems to me that languages that have exceptions 'baked in', such as Delphi and C# are much friendlier to use exception wise that languages such as C++ where exceptions are tacked on later. The fact that using exceptions in C++ is even optional should be a hint about their status within the language. <<

In C++ exceptions are optional because C++ is a multi-paradigm language.


>> You see it is hard to use exceptions safely in C++ because it is not a garbage collected language. <<
*blink*

And here I thought it was the finally keyword.
Fake Programmer
Saturday, August 02, 2008
 
 
What if you overrun a buffer and overwrite the "final" block code?
quant_dev
Saturday, August 02, 2008
 
 
>> What if you overrun a buffer and overwrite the "final" block code?

This is not in the domain of C++ exceptions.  Nor is what happens if you access invalid memory.  These are undefined behaviors in C++, so there's really no telling what'll happen.  Unless you have some sort of control over that from outside the C++ domain, such as the Windows operating system's Structured Exception Handling - which is different than C++ exception handling.

Saturday, August 02, 2008
 
 
Saying that does not make the problem go away.
quant dev Send private email
Saturday, August 02, 2008
 
 
>>  Saying that does not make the problem go away.

No, but if you want to discuss how to deal with those problems you should probably start a new thread, since C++ exceptions won't help and aren't designed to.
mwb
Saturday, August 02, 2008
 
 
My point is that it's the finally mechanism that makes languages such as Java and C# exception safe, not that they're garbage collected.  Take away the finally construct and they suddenly quit releasing files, network resources, et al (destructors would become a necessity).  IOW, you end up with the same problem you're imagining in C++.
Fake Programmer
Saturday, August 02, 2008
 
 
I thought "finally" is absolutely necessary until I started using the smart pointer and reference counting.

The thing is, to make old code work like this demands almost a rewrite by skilled C++ programmers who adopt a common subset of C++ features. This is not easy to achieve at all.
Phil
Saturday, August 02, 2008
 
 
"No, but if you want to discuss how to deal with those problems you should probably start a new thread, since C++ exceptions won't help and aren't designed to."

What I meant is that C++, being a language which does not protect the code from being destroyed during the run of the program, will never be fully "exception safe". No matter how hard you try.
quant_dev
Monday, August 04, 2008
 
 
I don't like the expression "exception safe". Anyway.

One thing for sure is that some C++ code has undefined behaviour. This means you can crash everything, and anything can happen.

class Widget
{
  public:
  Widget();
  void f();
}

Widget * p = NULL;
p->f();

Another thing is that you handle exceptions correctly. If you know opening a file and then reading from it can cause an exception, write your code in such a way that if the file has actually been opened and you get an exception while reading from it, you close it.

Exception safety won't save you if you make a bug.
Daniel_DL Send private email
Monday, August 04, 2008
 
 
C#, being a language that doesn't protect you from OS bugs, isn't truly "exception safe".  After all, said bug could corrupt the stack.

It's a matter of degrees, and if you've got a corrupted stack you have bigger problems to worry about.
Fake Programmer
Monday, August 04, 2008
 
 
Raymond Chen provided a good explanation of the issues here:

http://blogs.msdn.com/oldnewthing/archive/2004/04/22/118161.aspx

and in the follow up article here:

http://blogs.msdn.com/oldnewthing/archive/2005/01/14/352949.aspx

Summary: "It's easy to spot the difference between bad error-code-based code and not-bad error-code-based code: The not-bad error-code-based code checks error codes. The bad error-code-based code never does. ... On the other hand, it is extraordinarily difficult to see the difference between bad exception-based code and not-bad exception-based code."
ChrisN
Friday, August 08, 2008
 
 
"On the other hand, it is extraordinarily difficult to see the difference between bad exception-based code and not-bad exception-based code."

If your exception-based code is littered with error handling, then it's bad exception-based code.  If the error handling happens in a few small defined places and the code is relatively free of error handling code, it's probably good.
Almost H. Anonymous Send private email
Monday, August 11, 2008
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz