HMC Homepage      CS Home

An introduction to C++

How to Compile, Run, and Debug

GNU G++ is a C++ compiler that has become fairly standard on UNIX, VMS, and other machines nationwide. It is based on the (still-evolving) ANSI standard, with many extensions. G++ is produced by the Free Software Foundation, which makes many other GNU products, which are copyrighted but free.

Compiling with G++

  1. The command to compile a C++ program is g++. The g++ compiler reads a text file containing either C or C++ code, and compiles it into runable form. It checks some syntax, but will let a lot of things slip through. This can cause your program to bomb. Most C filenames end with .c but most C++ filenames end with .C (note the uppercase) or .cc or .cxx; the MS-DOS standard .cpp is not used on UNIX machines. If g++ reports a bad magic number or unknown type error during a compile, it probably means the compiler did not like the extension on your file.

  2. To compile a program, you will usually use command-line switches. These tell the compiler where to put its output, what libraries to use, etc. The simplest compile statement is this:

    % g++ hello_world.cc

    This compiles the code in hello_world.cc and produces a file a.out that you can run. Here are some useful command line options:

    1. If you want the output filename to be different, use -o :

      % g++ -o hello_world hello_world.cc

      This makes a file you can run (an executable) called hello_world, quite distinct from hello_world.cc, the source code.

    2. If you want to have the compiler list all warnings, use the -Wall option. For example:

      % g++ -Wall hello_world.cc

      This option will list more warnings than the compiler normally would, which is very helpful in debugging your code.

    3. If you use any external libraries in your program, use -l<libname> to include them. A common example is the math library:

      % g++ -o findpi findpi.cc -lm

      In which the -lm is the operative part.

    4. The -c option tells the compiler to just generate object code (.o files) and not link them into an executable. This is useful if you write a module you wish to use in many different programs, but don't want to recompile every time. For example, if you wrote a matrix operations module, you could compile it with

      % g++ -c matrix.cc

      This generates a file called matrix.o, which you can then include in compiling other programs just by adding it to the command line:

      % g++ my_matrix_prg.cc matrix.o

    5. If you plan to use symbolic debugging, use -g.

      % g++ -o big_program big_program.cc -g

      This will allow you to use GDB, one of the more popular debuggers. For more information about GDB, see the GDB Qref, or the gdb info pages ("info gdb").

Running your Program

  1. To run the program you just created, type

    % ./hello_world

    or

    % ./findpi

    or whatever filename you told the compiler to produce, with a ./ attached to the front. This tells the command shell that the executable is in the current directory. Remember, if you didn't use the -o switch, your file will be called a.out.

  2. It is recommended that you create subdirectories with mkdir for each of your assignments. This helps keep files straight. For example,

    % mkdir project1

    will create a directory called project1 in which you can store all the files (code and executables) for project 1. Also, once you are certain you will no longer need them, delete executable files.

    % rm hello_world

    Executables eat up your disk quota faster than you think, and you can always recompile later. Be careful not to erase your source code by mistake.

Debugging your Code

  1. G++ will only create the executable file if you have no syntax errors in your code. This is extremely unlikely. Taking the errors out, "debugging", is a long, painful, and frustrating process. As a general rule, start with the first error listed. Note its line-number. Go to that line in the program, and look for common errors: misspellings, missing semicolons, and case errors. That is, C++ is case- sensitive, so index and Index are different variable names. If you get errors with funny-looking names that appear nowhere in your program, like __stdin, you are having problems with your include files (#include lines in your code), or linking problems, such as forgetting to link in a library (see -l above).

  2. If you are using emacs or jove, getting to a line number is fairly easy. Type ESC-x or CTRL-z, then at the command-line type goto-line Then, type in the line number of your first error. Or even easier is the VI editor -- simply type the line you want to go to and hit "G". Since one error in your program may generate many errors when you compile, it is often helpful to recompile after you have fixed a few of the errors before proceeding. If you are working on an X terminal, it is useful to have one window for compiling and testing and another for editing. That way you can leave the list of errors on the screen in one window while fixing them in the other.

  3. If your program compiles and runs, but you get the error segmentation fault, bus error, bad results, or it just plain locks up, you have a logic error. The most common way to detect these types of errors is to put printf or cout statements in areas where you need to check the value of a variable. For example,
    for ( i=0 ; i<10 ; i++);
        {
        cout << i << '\n';  // this is for debugging purposes
        sum  += a[i];
        prod *= a[i];
        }
    

    The cout will print only one number, revealing that the supposed body of the for-loop is executed only once. The problem here is the semicolon after the for-loop. Another method for finding errors is learning to use the debugger GDB.

Pascal Hints

If you just took Pascal, and are having trouble adjusting, here are some common Pascal-related problems to watch out for.
  1. Using = and == correctly. = is for assignment, like the Pascal := but == is for comparison, like the Pascal =.
  2. Forgetting semicolons. Every C++ statement needs a semicolon after it, even before a }.
  3. Output all on one line. Remember, everywhere you'd use a WriteLn, put a '\n' at the end of your string to be printed.
  4. C++ does not use the word "then" after if statements, and the condition in an if, while, or for must be contained in parentheses.
  5. C++ declares variables int i, j, k; not "i,j,k : Integer;".
  6. Multidimensional arrays are accessed as a[i][j] in C++, instead of "a[i,j]".
  7. Remember to allocate memory for all your pointers. In C++, use the new and delete commands to control memory allocation. Make sure you never delete the same pointer more than once.
  8. Quotes are different. Pascal uses single quotes inside WriteLn statements; C++ uses double quotes for all strings (such as inside cout and printf statements). Single quotes in C++ denote single characters: 'a' is fine but 'goodbye' isn't.

Notes:

If you have further questions, or just want to get the gory details about command-line options, type "man g++" at your UNIX prompt. Also, the info pages "info g++" should be useful. For help interpreting errors reported by g++, access a good C++ reference manual or your local C++ guru. Remember, consultants are there to help, too.


Copyright (c) HMC Computer Science Department. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License.''

HMC Computer Science Department
Contact Information
Last Modified Tuesday, 22-May-2001 16:17:26 PDT