8

In your opinion, do you think it is a waste of time to make checks that you know there is no possible way of it being there/not being there, or would you just put it there just in case there is a bug or something? For example, below checks to see if a button is visible, then music is playing, but there is no way for that button to be shown without the music playing:

if (buttonVisible)
    if ([music playing] == true) //is always true if the button is visible
        [music stopPlaying];
  • 1
    better, avoid checks like that; if you're calling `[music stopPlaying]`, it shouldn't matter if some button is visible (that's view stuff) and if the music isn't playing, it should just do nothing – amara Dec 30 '12 at 21:18
  • @sparkleshy: there may be a good reason to have a tight relation between the UI and the `music stopPlaying`. The following code may be simply within a method which is executed on button click, so while `music stopPlaying` is business logic, the actual piece of code is not. – Arseni Mourzenko Dec 30 '12 at 21:27
  • @MainMa: yes ... if the method is executed on button click, then _the button is visible_ – amara Dec 31 '12 at 00:55
  • @sparkleshy: good point. – Arseni Mourzenko Dec 31 '12 at 00:59
  • 1
    @sparkleshy it's possible to fake button clicks, especially on windows! – James Dec 31 '12 at 04:02
  • 1
    @James: it's possible to fake anything (including the button programmatically registering as visible). besides, who cares if it's fake? – amara Dec 31 '12 at 15:37
  • "there is no possible way..." famous last words. – JeffO Dec 31 '12 at 17:08
  • Man, you don't know how many times the phrase "that condition is impossible" seems to crop up while debugging. – SnoopDougieDoug Dec 31 '12 at 18:23

3 Answers3

12

What if:

  • Some other application manipulates the window and renders the button visible while the music is not playing?

  • A thread stops the music and is about to hide the button when you check the visibility of a button?

  • Some other developer modifies the code, without knowing the relationship between the visibility of the button and the music state?

  • You modify the code since the requirements changed and instead of hiding the button, you were required to only disable it?

  • You replace the button by some other control?

In other words:

  1. You shouldn't check for a condition if “there is no possible way of it being true/false”. For example the if block in the following code is redundant and should be removed:

    assert(input > 0);
    var i = input * 2;
    if (i > 0)
    {
        // Do something useful.
    }
    
  2. You should check for a condition in a case like the one you illustrated, since there is no strict and reliable relation between the visibility of a button and the state of the music.


Note that in your code, what you should omit is the first if. Since you simply want to stop the music (and for a reason, you can't just call music stopPlaying if the music is not playing), the only check you should do is if ([music playing]). That the button is visible or not doesn't matter. You don't care whether it is visible or not, enabled or not, or even if it exists.

For example something like:

if ([button visible])
    if ([music playing])
        [music stopPlaying]
        [button hide]

could be rewritten as:

if ([music playing])
    [music stopPlaying]
    [button hide]

if the visibility of the button relies on the state of the music. Data binding, if supported by your language/framework, is even better:

[button visibility=(bind:music state)]

// Later in code:

if ([music playing])
    [music stopPlaying] // The button is hidden automatically
Arseni Mourzenko
  • 134,780
  • 31
  • 343
  • 513
  • Thanks for the quick response. I'll have to start thinking more outside the box from now on I guess. – cory ginsberg Dec 30 '12 at 21:16
  • +1: Very good points. Some checks are superfluous in the current version of a piece of software, but become relevant if another programmer changes the code (or if you change it yourself, months later) so that certain conditions are no longer guaranteed to be valid. The safest way to go is to never assume anything about the rest of the program. – Giorgio Jan 01 '13 at 10:10
  • "For example the if block in the following code makes no sense:" Err What? If `input = 1` then it passes the assert, but `i` would equal `0` and fail the `if` in many languages (e.g. C# with input being an int). However if `input` is bigger than `2` then `i` would be larger than `0` and the `if` would pass. – NPSF3000 Nov 27 '15 at 11:00
  • @NPSF3000: true. I corrected the answer by using multiplication instead. Thank you for noting the original error. – Arseni Mourzenko Nov 27 '15 at 11:10
  • @MainMa thank you for correcting the error using multiplication. Of course, in `input` is `2000000000` then the result after multiplication by 2 is `-294967296`. One should be very careful before saying something is 'impossible' without knowing the full implications. – NPSF3000 Nov 27 '15 at 11:17
2

I'd liken these seemingly superfluous checks to activating your directional when turning on a vacant street.

On that vacant street, you've done your due diligence, scanned your surroundings, and checked your rear view mirror. There's nobody around, so why should you activate your directional?

Here's why: Because next time you drive down a similarly vacant street, you might miss a car in your blind spot.

The act of activating your car's directional communicates intent. Also, it's just a good habit to get into.

Similarly, I recommend that you include such checks in your code wherever you think they are applicable. These checks will communicate intent to future programmers who will read your code. And in light of the fact that your code will be modified in the future, you can't predict the context of future method calls.


EDIT: Per @Chuck Conway's comment, it is probably best to convert most of these if checks to either assert statements or if (not 'X') then throw statements. An encapsulating if statement might cloak a very unexpected bug!

Also, I agree with his point about simplicity. There's a fine line between adding some additional checks and adding junk that will confuse future programmers. So be judicious.

Jim G.
  • 8,006
  • 3
  • 35
  • 66
  • 1
    +1 Nice analogy! But I disagree. By adding a conditional check, you might have just covered up a bug (or blind spot in the analogy's case). Keep it simple, if it's not needed then don't code it. Adding code for **possible** future cases or coders is a form of future proofing. By writing simple code, you are enabling future coders easily grok your code. – Chuck Conway Dec 31 '12 at 21:48
1

In your opinion, do you think it is a waste of time to make checks that you know there is no possible way of it being there/not being there, or would you just put it there just in case there is a bug or something?

There are three possibilities, it's implossible

int i = 0;
if (i==1 && i==2) {
 // useless test
}

It's possible but requires a change in the code somewhere.

int i = 0;
if (i>0) {
// line above should prevent this from happening.
// extreme case, if this branch is executing someone did something wrong
}

And finally it could simply be an invalid state, something which you don't think can happen given good data.

The first case is a total waste of time, no change to the code or the user input can result in that test succeeding. The second case is MOSTLY useless, but a variation on it can be useful. Basically, the second case as presented requires a change in the code to for that branch to be take, but a more complex example could be useful in validating an assumption that is baked into the following algorithim, but is not inherently enforced.

For instance, if instead of an int, it was creating a uninitialzed User, then a check that the name was empty could theoretically be valid -- the User could be changed so that a default name is supplied, and if a write once property was changed so that the default name could be changed, it could mess things up.

But really, there are better ways of testing for such things (unit test for instance, although that's not really what they are for).

Finally, there's the last case -- and whether you test for that depends upon what you can do about it that is useful. And just how unlikely you think it is -- if it is realistically never going to happen, then testing for it is a waste of time. If on the other hand, it shouldn't happen but can, then by all means catch it if you can do something useful.

jmoreno
  • 10,640
  • 1
  • 31
  • 48