How To Debug g++ Compile-time Errors

<< Back

On This Page

Cygwin!

Introduction

Explaining compiler error messages is difficult because there are so many ways to make errors. Also, many different mistakes can cause the same error message. Thus, this "How To" does not attempt to explain all possible compile-time errors and all possible causes. Instead, it covers only the most common problems and the error messages they produce.

Kinds of Programming Errors

We can classify programming errors into three general types:

  • Syntax errors
  • Run-time errors
  • Logic errors

The easiest errors to debug are syntax errors.

Syntax Errors

  • In programming terms, syntax is the arrangement of words for a programming language
  • Violation of the "grammar" rules of the programming language
  • For instance: forgetting a semicolon
  • Syntax errors are discovered by the compiler
  • Your program will not compile if you have a syntax error
  • Instead, you will see error messages like:
    fiddle.cpp: In function `int main()':
    fiddle.cpp:6: error: parse error before `return'
    

Errors Versus Warnings

  • If you violate a syntax rule, the compiler gives you an error message
  • Sometime the compiler will give you are warning message instead
  • For example:
    erroneous.cpp:10:1: warning: "/*" within comment
    
  • This indicates that your code is technically correct
  • However, the code is unusual enough that it may be a mistake or is otherwise undesirable
  • Thus, you lose points for warning messages in your programming assignments

Run-time Errors

  • Error conditions are sometimes detected by the computer at run-time
  • For example, running the following program will eventually create a run-time error:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    #include <iostream>
    using namespace std;
    
    void runtimeError() {
        cout << "Are we through yet? ";
        runtimeError();
    }
    
    int main() {
        runtimeError();
        return 0;
    }
    
  • The error messages looks like:

    3 [main] fiddle 4588 _cygtls::handle_exceptions: Exception: STATUS_STACK_OVERFLOW
        472 [main] fiddle 4588 open_stackdumpfile: Dumping stack trace to runtimerror.exe.stackdump
     974501 [main] fiddle 4588 _cygtls::handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
     985548 [main] fiddle 4588 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)

Logic Errors

  • Errors in the program's algorithm
  • For example: subtracting rather than adding in an arithmetic formula
  • Computer does not recognize these types of errors
  • Makes them the most difficult to diagnose

Anatomy of a Syntax Error Message

Debugging compiler messages means that you have to read them and extract the important information from them. For example, the following error message:

fiddle.cpp: In function `int main()':
fiddle.cpp:6: error: parse error before `return'

tells you several important things:

  1. the name of the program:
    fiddle.cpp: In function `int main()':
    
  2. the function where the error occurs:
    fiddle.cpp: In function `int main()':
    
  3. the line number of the error:
    fiddle.cpp:6: error: parse error before `return'
    
  4. the error message:
    fiddle.cpp:6: error: parse error before `return'
    

Thus, even scary-looking error messages can give you important clues for fixing problems.

How To Debug Syntax Errors

Repeat the following process until all the compiler errors are gone.

  1. Find the first error (or warning) only.

    You should look at the first error or warning and ignore the rest. Often the first error or warning causes all the rest of the errors and warnings. Reading any error or warning beyond the first is often a waste of time.

  2. Analyze the first error or warning.

    Find the line reported by the first error or warning. This is the line where the compiler first got confused or spotted a potential problem. Look at this line in your code and try to spot the problem. The error message may provide clues as to the problem. If you cannot see a problem on that line, look for a problems on lines just before the reported line.

  3. If you cannot find the error in your code, then look at the causes of common errors in the next section.

    Most times, you will spot the error. If you do not, then compare the first error message with those listed below. If you still cannot find your error, show it to the instructor. He will help you find and correct the problem. You can either bring it to him in person or email him.

  4. After correcting the first error or warning, recompile your program and repeat these steps until no errors are reported by the compiler.

Some Common Syntax Error Messages

The following sections describe common error messages and their causes. These messages include:

missing terminating " character

This error is usually caused by a missing double quote ("). For example, the following code:

#include <iostream>
using namespace std;

int main() {
    string message = "Hello world!;
    cout << message << endl;
    return 0;
}

generates the following error:

fiddle.cpp:5:22: missing terminating " character
fiddle.cpp: In function `int main()':
fiddle.cpp:6: error: parse error before `<<' token

The fix, of course, is to add the missing double quote.

parse error at ..., parse error before ...

This is a general-purpose syntax error and is often caused by:

  • A missing semicolon (;)
  • A missing curly bracket
  • A missing << between terms of cout
  • A missing >> between terms of cin

This error is frequently caused by a missing semicolon. For example, the following code:

#include <iostream>
using namespace std;

int main() {
    cout << "Hello world!" << endl
    return 0;
}

generates the following error:

fiddle.cpp: In function `int main()':
fiddle.cpp:6: error: parse error before `return'

Adding a semicolon (;) at the end of the line cout << "Hello world!" << endl will get rid of this error.

Notice that the error refers to line 6, but the error is actually on the previous line. This is quite common. Since C++ compilers are lenient about where you place whitespace, the compiler treats line 5 and line 6 as a single line that reads as follows:

cout << "Hello world!" << endl return 0;

Since this is incorrect syntax, the compiler complains.

Another cause of these types of errors is a missing curly bracket. For example, the following code:

#include <iostream>
using namespace std;

int main() {
    if (true) {
        cout << "Hello world!" << endl;
    return 0;
}

generates the following error:

fiddle.cpp: In function `int main()':
fiddle.cpp:8: error: parse error at end of input

Because there is no closing curly bracket for the if statement, the compiler thinks the curly bracket that terminates the main() function actually terminates the if statement. When it does not find a curly bracket on line 8 of the program to terminate the main function, it complains. Adding the closing curly bracket fixes the problem

#include <iostream>
using namespace std;

int main() {
    if (true) {
        cout << "Hello world!" << endl;
    }
    return 0;
}

One good way to avoid this problem is to type both members of a matching pair of brackets before you fill them in.

... undeclared

This error is often caused by:

  • Changing the case of a variable after declaring it
  • Forgetting to declare a variable
  • Forgetting to put double quotes around a literal string

For example, the following code:

#include <iostream>
using namespace std;

int main() {
    string message = "Hello world!";
    cout << Message << endl;
    return 0;
}

generates the following error:

fiddle.cpp: In function `int main()':
fiddle.cpp:6: error: `Message' undeclared (first use this
   function)
fiddle.cpp:6: error: (Each undeclared identifier is
   reported only once for each function it appears in.)

The fix is quite simple: pay attention to the case of your identifiers. Remember that C++ is case sensitive.

Another common cause of this error is forgetting to declare a variable. For example, the following code:

#include <iostream>
using namespace std;

int main() {
    cout << message << endl;
    return 0;
}

generates the following error:

fiddle.cpp: In function `int main()':
fiddle.cpp:5: error: `message' undeclared (first use this
   function)
fiddle.cpp:5: error: (Each undeclared identifier is
   reported only once for each function it appears in.)

Fix it by declaring the message variable before using it.

Yet another common cause of this error is forgetting to put double-quotes (") around strings. For example, the following code:

#include <iostream>
using namespace std;

int main() {
    cout << Hello world! << endl;
    return 0;
}

generates the following error:

fiddle.cpp: In function `int main()':
fiddle.cpp:5: error: `Hello' undeclared (first use this
   function)
fiddle.cpp:5: error: (Each undeclared identifier is
   reported only once for each function it appears in.)
fiddle.cpp:5: error: parse error before `!' token

The fix is to put double quotes around the message you want to display:

undefined reference to ...

This error is often caused by typing the name of a function or variable incorrectly. For example, the following code:

#include <iostream>
using namespace std;

void printMessage();

int main() {
    printMessage();
    return 0;
}

void PrintMessage() {
    cout << "Hello world!" << endl;
}

generates the following, rather confusing, error:

Temp/cchu6zaY.o(.text+0x1f):fiddle.cpp: undefined reference
   to `printMessage()'
collect2: ld returned 1 exit status

The fix, however, is very simple. C++ is case-sensitive. Each time you refer to a function you must use the same case.

<< Back

Last Updated: February 14 2009 @20:01:15