Comments on: Defensive Programming I was about to say the same thing. Use asserts in your debug builds, but have the defensive programming in there for release builds. A user should never have to see a segfault, stack trace from an exception being thrown, or anything else. I was about to say the same thing. Use asserts in your debug builds, but have the defensive programming in there for release builds. A user should never have to see a segfault, stack trace from an exception being thrown, or anything else.

]]>
By: Ricardo Santos/2011/05/12/defensive-programming/#comment-3960 Ricardo Santos Thu, 12 May 2011 21:33:01 +0000 You... you <em>do</em> know what assertions are, right? What they are, what they're for, and how they're used in practice? You… you do know what assertions are, right? What they are, what they’re for, and how they’re used in practice?

]]>
By: Fabrice Lété/2011/05/12/defensive-programming/#comment-3949 Fabrice Lété Thu, 12 May 2011 19:46:06 +0000 There's a time and place for defensive programming though. When you have a large team, its far better to detect and log the error, and keep running, than it is to just crash. Otherwise, a bug in one system will waste A LOT of production time for people whose work has nothing to do with that system. If you have a bug in some gameplay data, you don't ever want the engine to crash because of that bug, when a level designer is just trying to preview his level. Defensive programming is a good idea when there's a strong likelihood that you won't always have correct data passing through that code, and incorrect data is going to cause a crash. It's especially a good idea if the crashes are going to waste your team's time (and they will). For example: Suppose you have tens of thousands of a certain type of asset (e.g. animation) and because of an exporter bug, a few hundred of them contain an unexpected combination of data that occasionally causes the engine to crash. You can fix the bug in the animation exporter, you can try and get somebody to manually re-export all of the affected animations, but sometimes its had to be 100% sure that you got them all. Meanwhile, team members working on totally unrelated things will experience crashes because of the bad data. In a situation like that, the first thing I would do would be to put in some defensive code to detect the unsafe data and avoid crashing. Only then would I fix the exporter, and try to repair existing data with a script or get someone to re-export the affected animations. Later, I might try to remove that defensive code but (if we're being totally honest here) other more important things would probably distract me and the game would probably ship with that defensive code in place. There’s a time and place for defensive programming though. When you have a large team, its far better to detect and log the error, and keep running, than it is to just crash. Otherwise, a bug in one system will waste A LOT of production time for people whose work has nothing to do with that system. If you have a bug in some gameplay data, you don’t ever want the engine to crash because of that bug, when a level designer is just trying to preview his level.

Defensive programming is a good idea when there’s a strong likelihood that you won’t always have correct data passing through that code, and incorrect data is going to cause a crash. It’s especially a good idea if the crashes are going to waste your team’s time (and they will).

For example: Suppose you have tens of thousands of a certain type of asset (e.g. animation) and because of an exporter bug, a few hundred of them contain an unexpected combination of data that occasionally causes the engine to crash. You can fix the bug in the animation exporter, you can try and get somebody to manually re-export all of the affected animations, but sometimes its had to be 100% sure that you got them all. Meanwhile, team members working on totally unrelated things will experience crashes because of the bad data.

In a situation like that, the first thing I would do would be to put in some defensive code to detect the unsafe data and avoid crashing. Only then would I fix the exporter, and try to repair existing data with a script or get someone to re-export the affected animations. Later, I might try to remove that defensive code but (if we’re being totally honest here) other more important things would probably distract me and the game would probably ship with that defensive code in place.

]]>
By: Jare/2011/05/12/defensive-programming/#comment-3937 Jare Thu, 12 May 2011 13:56:20 +0000 Defensive programming is often criticized from two angles: <strong> - it hides programming errors by avoiding crashes.</strong> This argument implies that you intend to verify the correctness of your program depending on whether it crashes. That's incredibly short-sighted in my opinion. You should be checking and logging anything unexpected and/or wrong and include appropriate context information, but if you know your program will not crash, you will be more consistent in doing this. Also the ability of a program to continue working after a failure greatly increases your ability to inspect and debug the problem, which is invaluable in hard to reproduce cases. <strong> - it reduces performance because of extra validation and correction code.</strong> This should be addressed like any other performance issue, by worrying about performance-sensitive or often-used parts of the code, and using configuration-dependent checks (a-la assert()). However, a strict policy of using defensive programming may help you avoid multiple checks of the same error, for example, if you know your array container checks the index against the container bounds, you don't need to check it yourself every time you access the array. In the end many programmers will have almost religious feelings about this, but I have absolutely zero doubts that properly used defensive programming will produce much more robust software with a lot less test and debugging effort. Defensive programming is often criticized from two angles:

– it hides programming errors by avoiding crashes.
This argument implies that you intend to verify the correctness of your program depending on whether it crashes. That’s incredibly short-sighted in my opinion. You should be checking and logging anything unexpected and/or wrong and include appropriate context information, but if you know your program will not crash, you will be more consistent in doing this. Also the ability of a program to continue working after a failure greatly increases your ability to inspect and debug the problem, which is invaluable in hard to reproduce cases.

– it reduces performance because of extra validation and correction code.
This should be addressed like any other performance issue, by worrying about performance-sensitive or often-used parts of the code, and using configuration-dependent checks (a-la assert()). However, a strict policy of using defensive programming may help you avoid multiple checks of the same error, for example, if you know your array container checks the index against the container bounds, you don’t need to check it yourself every time you access the array.

In the end many programmers will have almost religious feelings about this, but I have absolutely zero doubts that properly used defensive programming will produce much more robust software with a lot less test and debugging effort.

]]>
By: Defensive Programming » #AltDevBlogADay | Guide 2 Serv Online/2011/05/12/defensive-programming/#comment-3931 Defensive Programming » #AltDevBlogADay | Guide 2 Serv Online Thu, 12 May 2011 13:14:27 +0000 Good point and nice articel but you forgot to talk about logging. If your right a method that doesn't crash on bad inputs, you should also log that an input was bad. It seems you'll be able to get the best of both worlds. Good point and nice articel but you forgot to talk about logging.
If your right a method that doesn’t crash on bad inputs, you should also log that an input was bad. It seems you’ll be able to get the best of both worlds.

]]>
By: Viktor/2011/05/12/defensive-programming/#comment-3920 Viktor Thu, 12 May 2011 08:50:11 +0000 hmm, seems to me that if you don't return NULL, you will need public functions to CheckItemExists(). Maybe that's possible because the item is registered in several databases, but otherwise you just have to compare with mItemInstances.end() regardless. I'm all for catching the errors as early as possible. hmm, seems to me that if you don’t return NULL, you will need public functions to CheckItemExists(). Maybe that’s possible because the item is registered in several databases, but otherwise you just have to compare with mItemInstances.end() regardless.

I’m all for catching the errors as early as possible.

]]>