Errors of Intent

An "error of intent" - also called a "logic error" - has occurred when your code compiles and runs without crashing but does not do what you intend. Typically you discover this because the output is incorrect. The methodology for debugging such errors is much the same as for run-time errors. The principal difference is that you do not have a line number from which to begin debugging. Instead, you should place print statements at strategic places in your code to track down the cause of the error, or trace your program's execution with DrJava.

One good preliminary step is to ensure that all of the code you expect to be executed actually gets executed. For example, consider the following code:

01  if( numPlayers == 8 && ! isDone )
02  { 
03      ...
04  }

Even though you believe that the body of this if statement is entered at runtime, you should place a breakpoint on its first statement (line 03) or insert a print statement at the beginning of the then-clause (i.e. between lines 02 and 03) and verify that the body is being executed. If in fact it's not being executed, then setting a breakpoint at the if statement and examining the values of numPlayers and done, or preceding the if-test by

System.out.println( "numPlayers = " + numPlayers + " and done = " + done )
should help identify the problem.

We will next discuss two common kinds of logic error.

  1. Blank console window
  2. Short-circuited boolean expressions

Blank console window

If your program runs but does not do anything (there is no output to the console or it just sort of "stalls"), then there is a good chance that your program is stuck somewhere in an infinite loop. This usually occurs with while loops, but can happen with a for loop as well.

One way to discover an infinite loop is to add a print statement at the beginning of each loop in your code. For example:

01  while (i >= 0)
02  {
03     System.out.println("In loop A.");
04     //...
05  }

You will know you are stuck in an infinite loop if your console output looks something like this:

In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
In loop A.
[...and so on, seemingly forever.]

To debug this problem, ensure that the while test (or the termination clause of a for loop) will eventually evaluate to false somewhere within the body of the loop because of a change to one of its constituent variables. If it's not obvious why this isn't happening, step through the body of the loop, watching the value of the variables contained in the termination test.


Short-circuited boolean expressions

Remember that Java does not evaluate an entire compound boolean expression if it doesn't have to because it can predict the final result without futher evaluation. This is called short-circuit evaluation. It is summarized in the following table.

Scenario Java's Short-circuit Evaluation Rules
//say A and B are boolean expressions
if( A && B )
{ //...
}

If A is true, then B is evaluated.

If A is false, then B is not evaluated.

//say A and B are boolean expressions
if( A || B )
{ //...
}

If A is true, then B is not evaluated.

If A is false, then B is evaluated.

This can become a problem only if the portion of the compound expression not being evaluated changes the value of a variable whose value you need later, typically by calling a method. For example, consider

if( x > 0 || readNextValue() )
{ 
    ...
}

where readNextValue() both reads the next input value required by your program - a value you actually use later in the code - and returns true or false, depending on whether it is successful doing so. But readNextValue() will not be called if x is positive. This kind of logic error is most easily discovered either by tracing program execution, stepping into the if-test, or by adding a print statement at the beginning of readNextValue().


Created by Terry Anderson (tanderso at uwaterloo dot ca) and adapted for CS 133 by JCBeatty. Last modified on 24 Sep 2006.