Holy cow, I wrote a book!
The great thing about parameter validation is that there are people who say that only idiots would have it, and other people who say that only idiots wouldn't.
Back in the old days, Windows didn't do parameter validation. If you called a function with an invalid window handle, your application crashed. If you called a function with an invalid pointer, your application crashed. If you called a function with an invalid bitmap handle, your application crashed.
There was a lot of crashing going on.
These crashes manifested themselves in the infamous Unrecoverable Application Error dialog, commonly known as the UAE message.
Windows 3.1 added parameter validation to all of the functions in KERNEL, USER, and GDI. If an application passed an invalid window handle, then instead of crashing, it just got an error back.
KERNEL
USER
GDI
This change was met with derision. "Oh, I'm so impressed. You finally got around to doing something you should have been doing all along. Not doing parameter validation was a totally idiotic decision."
But nowadays, parameter validation is out of fashion again. If you detect an invalid parameter and return an error code, then all you're doing is masking a latent bug in the application. It should crash and burn with a big red fat'n'ugly blinking exception.
In other words, we should go back to the way things were before we added parameter validation. (Well, except that the bit fat ugly exception wasn't red and it didn't blink.)
Who's the idiot now?
Igor is clearly right...
If a memory allocation fails, the Windows should blue-screen.
If a non-existent file is open, white-noise should be played as loud as possible and all the window contents (if any) should flash in inverse video.
If the user mistype a command in the shell, the screen should rapidly blink various colors randomly non stop until the computer is turned off.
If you click on a dead URL in the web browser, all fans should be stopped and your CPU and graphics card left to melt.
You're either a real man or you don't touch computers. That's were the line is drawn. Igor knows.
If the application is going to cause an Access Violation then it should die as fast as possible so as not to mask a latent bug.
However, the OS should not crash and burn. I think it is proper that the OS validates input and returns an error code on bad input.
The difference here is that the app is going down by its own doing. The OS didn't do anything wrong, it is just dealing with foreign programs that probably should not be trusted (these days, at least).
The answer is actually simple: when running for your QA dept, it should crash immediately; when running for your customer, it should silently keep going.
If the app crashed (for a lack of parameter validation), a lightning bolt should strike the programmer.
Each and every time.
Nice article Ray, but how on earth you keep track of all these comments you linked!!
One from 2008, other from 2007 for an article in 2009 which speaks about valid point and links both. Impressed.
More seriously, I'm surprised people are still doubtful about error checking.
1. Only the function doing the actual work knows all the failure modes and thus can really validate the parameters.
2. Those failure modes can change from implementation to implementation, making it nigh impossible for the caller to know what and how to validate.
3. Some validation is impossible. Trying to create a file with a unique name? You need to open it and see if the open fails. Need to know if you can read a file? Only opening and reading it can actually validate that you can.
4. It reduces code clutter: validation is only done in one place and it is done consistently. If the caller validates, then they'll get it wrong half of time. (Being generous here.)
5. Try-and-handle-failure is a common coding practice and usually leads to clearer code, at least in some languages.
6. Failure is often not a local property but a global one. When something fails, the correct failure mode is usually to fail the whole operation. Most language still don't get this right. Exception is a valiant attempt to make the error handling more global, but the true answer might lie in some form of aspect programming where the error handling policies are designed globally based on whole-program semantics.
>> Who's the idiot now?
All programmers are idiots some of the time, and some programmers are idiots all of the time. You cannot claim to be an experienced programmer unless you provide provable claims to have indulged in various forms of idiocy over the years!
Not to start a flame war, but I blame this "everything throws an exception" mentality on the rise of programming paradigms that get further and further away from the hardware. Anyway, my belief is that (at the Win32 API level) exceptions should only be raised in exceptional circumstances. To me, passing an invalid window handle to some function doesn't qualify. Yes, this could potentially mask serious problems, but the people who don't check return values are the same people who would catch and swallow all exceptions.
Here is the red, blinking exception:
http://haftbar.de/wp-content/guru-meditation_error.gif
The red box blinked at 1Hz.
Captcha 066; Wow, only one digit off.
@Gabe: Suppose the customer's software deals with money. If some sort of corruption occurs that affects the totals, then it could run incorrectly for hours (or days, if no end-of-day accounting is performed). In a situation like that, it would definitely be better for the program to exit as soon as the error condition is detected, when diagnostics might be more useful.
Yeah, validation is for p*ssies!!!
Especially if writing web-apps! After all, in popular use "injection" is almost synonymous to "innoculation", so allowing users to inject anything they want can only make your system healthier right?
Oh look! User "Fred; drop user app_user cascade; " logged in again!
I'm all for crashing and burning when in debug mode, because it makes errors obvious to the programmer.
However, when the app is in the user's hand and an error happen, the operation should just fail silently instead of taking the app down in flames.
I will say this: parameter validation certainly makes triaging by call stacks
easier.
Hey, Raymond, would yo consider a star for Gabe?
@John ("people who don't check return values are the same people who would catch and swallow all exceptions")
No, these people are e.g. dumb to know they need to check retval or e.g. either lazy. If exception is thrown at them, they would do nothing if they are dumb (don't know they can catch) and they would do nothing if they are lazy (try/catch around each call is a much bigger pita than an if). So it clearly works better - dumb and lazy are punished ;-).
Coming from the .NET world, seems to me the only reason these two views are incompatible at all is the limitation of the technology of error codes (as opposed to exceptions). (If I remember rightly, Eric has strong views on error codes *in general* as opposed to exceptions, so I'm making no comment on the *overall* tradeoffs, just the ones applicable to this particular question)
The problem with error codes is that the default action in the case of an inept programmer is that the code gets ignored. With exceptions, the default action in the case of an inept programmer is that the application blows up.
So in a world which supports exceptions, the answer is "of course you should do parameter validation, *so that* you can make the application blow up when the parameters are wrong" - and incidentally pass along a helpful message in debug mode telling the programmer which parameter they passed was incorrect.