Hacker News new | past | comments | ask | show | jobs | submit login

"Checks all arguments and asserts critical assumptions in code "

Wait, I just finished code complete, and it told me that you specifically _don't_ check all arguments throughout your program. Instead, you choose a list of classes at that will check arguments for input as a firewall, and assume all classes behind those logically will receive the correct, sanitized input.

Did I misunderstand this?




If you're paranoid (eg, programming embedded where it absolutely, positively, should not fail), you always check all arguments and return values. Sometimes libraries shipped from the vender are not perfect, sometimes the vendor's compiler will do something, ahem, unexpected with your return value in some edge case where you've exceeded the stack. I'll agree that wrapping with inlining is a good idea to make code readable, and these days you usually don't have to worry about a lot of hardware limitations (especially in the general case: desktop/Android/iOS/web/etc).


> programming embedded where it absolutely, positively, should not fail [means] you always check all arguments and return values

Let's distinguish "checking" invariants, preconditions, and postconditions from blithely propagating logic errors as error codes all the way up the stack. If you're programming in "paranoid mode", as it were, and you detect inconsistent state, you should abort the program. If you don't, you're in uncharted territory and you have no idea how your program will act. If you abort the program and restart the system, you'll probably end up back in a useful state.

Many, many times, I've seen code like the following:

    HRESULT hr;
    hr = DoComplexThing();
    if (FAILED(hr)) { RaiseFailFastException (...); }
Say someone passes a NULL pointer to a function somewhere deep inside DoComplexThing's implementation that doesn't expect NULL. If this function helpfully "checks" all parameters, detects the NULL, and returns E_POINTER, E_POINTER will probably propagate all the way up the stack to the top level, where we'll abort the program. Now you have a crash report, but you have no idea where the problem actually _is_.

If this function had instead not checked the NULL pointer and crashed or explicitly asserted its preconditions instead of treating contract violation as a runtime error, the problem would be a lot easier to diagnose.

In general, you can separate problems into two classes: logic errors and runtime errors. Logic errors are indications of the program being written incorrectly. Your program should blow up when it detects one. Runtime errors are errors that could conceivable occur at runtime due to reasons outside the program's control (e.g., removing an SD card). Only runtime errors should be propagated using your error reporting mechanism of choice.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: