{ }codelper

Learn › Java

Going further · 22

Common mistakes and error messages

How to read error messages, and the mistakes every language shares: off-by-one, = vs ==, integer division, null, out-of-range indexes.

Some mistakes show up in every language.
Learn them together with how to read error messages.
The example below checks that an index is in range and that the divisor isn't 0 before using them.

import java.util.Scanner; public class Main {    // int에는 null을 못 담아서 Integer로 돌려줘요    static Integer get(int[] a, int i) {        if (i >= 0 && i < a.length) return a[i]; // 안 막으면 ArrayIndexOutOfBoundsException        return null;    }     static Integer safeDiv(int x, int y) {        if (y == 0) return null; // 안 막으면 ArithmeticException        return x / y;    }     public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt();        int[] a = new int[n];        int sum = 0;        for (int i = 0; i < n; i++) { // i <= n 이면 한 칸 넘어가요            a[i] = in.nextInt();            sum += a[i];        }        int q = in.nextInt();        for (int t = 0; t < q; t++) {            int i = in.nextInt();            Integer v = get(a, i);            System.out.println(v == null ? "a[" + i + "]: out of range" : "a[" + i + "] = " + v);        }        int x = in.nextInt(), y = in.nextInt();        Integer d = safeDiv(x, y);        System.out.println(x + " / " + y + (d == null ? ": cannot divide" : " = " + d));        System.out.println(String.format("average %.1f", (double) sum / n)); // sum / n은 2    }}
stdin
5
3 1 4 1 5
3
2 7 -1
7 0
stdout
a[2] = 4
a[7]: out of range
a[-1]: out of range
7 / 0: cannot divide
average 2.8

Key points

  • In an error message, look for the error name, the reason and the line number.
    In Python, read from the bottom line.
  • In compiled languages (C, C++, Java, C#), fix the first error first, even when there are many.
    The later ones are often knock-on effects.
  • Indexes run from 0 to n - 1, so a loop needs i < n.
    Writing i <= n steps one past the end: the off-by-one error.
  • = stores, == compares.
  • Before dividing, check the divisor isn't 0.
    Before using a value, check it isn't null.
  • Give every variable a starting value when you create it (int sum = 0;).

How each language writes it

PythonThe last line has the name and reason, like IndexError: list index out of range, with the line number just above.
Dividing by 0 raises ZeroDivisionError, calculating with None raises TypeError, an unknown name raises NameError.
a[-1] isn't an error but the last item, and if not v: also catches 0 (ask v is None)
JavaScriptAn out-of-range index gives undefined with no error, and 7 / 0 is Infinity.
"No value" is null and undefined, and undefined + 1 is NaN while null + 1 is 1, so it goes quietly wrong.
Compare with === ("1" == 1 is true)
TypeScriptSame as JavaScript
JavaThe first line is ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 5, and at Main.main(Main.java:12) below gives the line.
Dividing by 0 throws ArithmeticException, null throws NullPointerException (int can't hold it, so use Integer).
A variable with no starting value is a compile error: "might not have been initialized"
C#Out of range throws IndexOutOfRangeException, dividing by 0 throws DivideByZeroException.
"No value" is int?.
A variable with no starting value is compile error CS0165
C++a[i] doesn't check, so out of range is undefined behaviour; a.at(i) throws std::out_of_range.
Integer division by 0 is undefined behaviour too (usually a crash).
"No value" is std::optional.
int sum; starts with a garbage value
CArrays aren't checked, so out of range is undefined behaviour: a garbage value, another variable overwritten, or a crash.
Division by 0 and uninitialized locals behave as in C++
CraykonOut of range stops with "List only has indexes 0–4".
7 / 0 is Infinity; Mathf.Quot(7, 0) stops with "Can't divide by 0".
null + 1 stops with "Can't calculate with null" (joined to text it shows as 빈값), and an unknown name "hasn't been created yet"

Common mistakes

i <= n stepped past the endC · C++ · Java · C# · JavaScript · TypeScript

int sum = 0;
for (int i = 0; i <= n; i++)
    sum += a[i];

→ Java and C# throw an out-of-range exception, JavaScript adds undefined and gets NaN, and C quietly adds a garbage value

Write i < n.

The average came out wholeJava · C# · C · C++

int sum = 7, n = 2;
double avg = sum / n;

→ avg is 3.0: 7 / 2 is integer division, so the fraction is dropped first

Convert one side first: (double)sum / n.

= instead of ==C · C++ · JavaScript

if (x = 5) {
    puts("five");
}

→ No error: 5 is stored in x and the condition is always true (gcc -Wall warns about it)

Compare with ==.
Java and C# refuse to compile, Python raises SyntaxError (since 3.10: "Maybe you meant '=='"), and Craykon rejects it as a syntax error.

How languages differ
An error that stops your program is actually a favour.
The truly scary cases give a wrong value with no error, like out-of-range access in C/C++ or undefined in JavaScript.

Practice