Visual Studio Code and Syntax Errors
When someone writes code in a high-level language they might make some mistakes. Look at the following Java program.
public class App { public static void main(String[] args) throws Exception { int num1, num2, c; num1 = 5; num2 = 10; c = num1 + num2 + ; System.out.println(c); } }
Fortunately, Visual Studio Code detects syntax errors while you are typing and underlines them with a wavy red line, as shown in Figure 1.
All you have to do is correct the corresponding error and the red line will disappear at once. However, if you are not certain about what is wrong with your code, you can just place your mouse cursor on the erroneous line. Visual Studio Code will try to help you by showing a popup window with a brief explanation of the error, as shown in Figure 2.
Visual Studio Code and Runtime Errors
Now, look at the following Java program.
import java.util.Scanner; public class App { static Scanner cin = new Scanner(System.in); public static void main(String[] args) throws Exception { int num1, num2, c; System.out.print("Enter number A: "); num1 = Integer.parseInt(cin.nextLine()); System.out.print("Enter number B: "); num2 = Integer.parseInt(cin.nextLine()); c = num1 / num2; System.out.println(c); } }
The program may look perfect, but have you thought about the possibility of num2
being zero? Unfortunately, the way this program is written permits the user to enter a value of zero for variable num2
. If you try to execute this program, and enter a value of zero for num2
, Java’s compiler complains and displays the error “ / by zero” (Figure 3). Also, the compiler tells you that this runtime error happened when line 14 was executed!
Notice: Using a decision structure, the computer could determine whether it should perform this division. We won’ t deal with this problem right now! It was used just to demonstrate how Visual Studio Code displays a run-time error when it occurs.
Visual Studio Code and Logic Errors – Debugging Step-By-Step
Compared to syntax errors, logic errors are more difficult to find. Since Visual Studio Code cannot spot and mark logic errors, you are all alone! Let’s look at the following Java program, for example. It prompts the user to enter two numbers and calculates and displays the square of their sum. However, it contains a logic error!
import java.util.Scanner; public class App { static Scanner cin = new Scanner(System.in); public static void main(String[] args) throws Exception { int a, b, S1, Sl; System.out.print("Enter 1st value: "); a = Integer.parseInt(cin.nextLine()); System.out.print("Enter 2nd value: "); b = Integer.parseInt(cin.nextLine()); Sl = a + b; S1 = Sl * Sl; System.out.println("The square of sum is: " + Sl); } }
If you type this program into Visual Studio Code , you will notice that not a single line is underlined with a wavy red line, indicating any error. However, if you run the program and enter two values, 2 and 3, you will see for yourself that even though the square of the sum of 2 and 3 is 25, Visual Studio Code insists that it is 5, as shown in Figure 4.
What the heck is going on? Of course, for an expert programmer, correcting this error would be a piece of cake. But for you, a novice one, even though you are trying hard you find nothing wrong. So, where is the error?
Sometimes human eyes get so tired that they cannot see the obvious. So, let’s try to use some magic! Let’s try to execute the program step by step using the debugger. This gives you the opportunity to observe the flow of execution and take a closer look at the current values of variables in each step.
Place the cursor at the line where the statement System.out.print("Enter 1st value: ")
exists and hit the F9 key. A red bullet appears in the left margin as shown in Figure 5.
Start the debugger by selecting “Run → Start Debugging” from the main menu or by hitting the F5 key. By doing this, you enable the debugger and more buttons are displayed on the toolbar.
The program counter (the yellow arrow icon in the left margin) stops at the first line of the program, as shown in Figure 6.
Notice: The program counter shows you, at any time, which statement is the next to be executed.
In this step, the statement
is not yet executed. Click on the “Step Over” System.out.print("Enter 1st value: ")
button on the toolbar or hit the F10 key once. Now the statement
System.out.print("Enter 1st value: ")
is executed. Click on the “Step Over” button on the toolbar or hit the F10 key once more. Now the statement
is executed and the program waits for you to enter a value. In the “Terminal” window, type the value 2, and hit the “Enter ⤶” key.a = Integer.parseInt(cin.nextLine())
The program counter moves to the next Java statement. Click on the “Step Over” button twice. The next two Java statements are executed and the program waits for you to enter a second value. In “Terminal” window, type the value 3, and hit the “Enter ⤶” key.
In the Side Bar on the left, you can watch all the variables declared in main memory (RAM) and the value they contain during each step of execution, as shown in Figure 7.
Click on the “Step Over” button again. The third statement
Sl = a + b
is executed.
Click on the “Step Over” button once again to execute the fourth statement
S1 = Sl ** 2
. What you expected here was the sum of 2 and 3, which is 5, to be squared and assigned back to variable Sl
. Instead of this, the value 25 is assigned to the variable S1
, as shown in Figure 8.
Notice: Variable
Sl
is different fromS1
. The first one uses the characters S and L (in lowercase), while the second one uses the characters S and 1 (digit one).
Now it becomes more obvious to you! You mistakenly declared two variables in the main memory (RAM), the variable Sl
with a lowercase L and the variable S1
with a digit 1. So, when the flow of execution goes to the last statement, System.out.println("The square of sum is: " + Sl)
the value 5 instead of the value 25 is displayed.
Congratulations! You have just found the error! Click on the “Stop” button to cancel execution, correct the error by changing variable S1
to Sl
, and you are ready! You just performed your first debugging! Re-execute the program and you will now see that it calculates and displays the square of the sum correctly.
Debugging logic errors by adding breakpoints
Debugging step by step has a big disadvantage. You have to click on the “Step Over” button again and again until you reach the position where the error might be. Can you imagine yourself doing this in a large program?
For large programs there is another approach. If you suspect that the error is somewhere at the end of the program there is no need to debug all of it right from the beginning. You can add a marker (called a “breakpoint”) near where you think that the error might be, execute the program and when flow of execution reaches that breakpoint, the flow of execution will pause automatically. You can then take a closer look at the current values of the variables at the position where the program was paused.
Notice: When the program pauses, you have two options for resuming the execution: you can add a second breakpoint somewhere below in the program, click on the “Continue” button, and allow the program to continue execution until that new breakpoint; or, you can just use the “Step Over”
button and execute the program step by step thereafter.
The next Java program prompts the user to enter two values and then it calculates their sum, their difference, and their average value.
However, the program contains a logic error. When the user enters the values 10 and 12, the value 16, instead of 11, is displayed as the average.
import java.util.Scanner; public class App { static Scanner cin = new Scanner(System.in); public static void main(String[] args) throws Exception { double a, b, s, d, average; System.out.print("Enter 1st value: "); a = Double.parseDouble(cin.nextLine()); System.out.print("Enter 2nd value: "); b = Double.parseDouble(cin.nextLine()); s = a + b; d = a - b; average = a + b / 2; System.out.println("Sum: " + s); System.out.println("Difference: " + d); System.out.println("Average: " + average); } }
You suspect that the problem is somewhere at the end of the program. However, you do not want to debug the entire program, but just the portion in which the error might be. So, let’s try to add a breakpoint at the d = a - b
statement (see Figure 9). There are two ways to do this: you can click in the left margin on the corresponding line, or you can place the cursor at the line of interest and hit the F9 key.
Notice: You know that a breakpoint has been set when the red circle appears in the left margin.
Start the debugger by selecting “Run → Start Debugging” from the main menu or by hitting the F5 key. Enter the values 10 and 12 when requested in the “Terminal” window. You will notice that just after you enter the second number and hit the “Enter ⤶” key, the flow of execution pauses at the breakpoint (the corresponding line has yellow background highlighting it).
Notice: You can run a project by selecting “Run → Start Debugging” from the main menu or by hitting the F5 key.
Now you can take a closer look at the current values of the variables. Variables a
, b
, and s
contain the values 10.0, 12.0, and 22.0 respectively, as they should, so there is nothing wrong so far, as shown in Figure 10.
Click on the “Step Over” button once. The statement
d = a − b
executes and variables a
, b
, d
and s
contain the values 10.0, 12.0, −2.0, and 22.0 respectively, as they should, so there is still nothing wrong so far, as shown in Figure 11.
Click on the “Step Over” button once again. The statement
average = a + b / 2
executes and variables a
, average
, b
, d
, and s
contain the values 10.0, 16.0, 12, −2, and 22 respectively, as shown in Figure 12.
There it is! You just found the statement that erroneously assigns a value of 16.0, instead of 11.0, to the variable average
! And now comes the difficult part; you should consider why this happens!
After two full days of thinking, it becomes obvious! You had just forgotten to enclose a + b
inside parentheses; thus, only the variable b
was divided by 2. Click on the “Stop” button, remove all breakpoints, correct the error by enclosing a + b
inside parentheses and you are ready! Re-execute the program and see now that it calculates and displays the average value correctly.
Notice: You can remove a breakpoint the same way you added it: click on the corresponding breakpoint, or place the cursor at the line that contains a breakpoint and hit the F9 key, or right click on the corresponding breakpoint, and select “Remove Breakpoint”.