|
Compiling Basics
|
|
using g++
|
Presented in this document are some basic facts about, and techniques for, compiling and linking programs. In the CS Lab, we use the g++ compiler, a product of GNU, for compiling C++ code. Only a few of g++'s features are discussed below, but the GNU homepage has links to more complete documentation.
#include.
#include-ing a file has roughly the effect of inserting the
contents of that file where the #include line occured.
#included in other files.
Consider the following program.
To compile each of the source files, and create the appropriate object files, execute the following commands. The -g option enables the gdb and ddd debuggers to operate on the files that are created. The -Wall option forces all compiler warnings to be displayed (some warnings are suppressed by default). The -c option tells g++ to only compile the file (not to link, etc.).
$ g++ -g -Wall -c Item.cxx $ g++ -g -Wall -c ShoppingList.cxx $ g++ -g -Wall -c shop.cxx
Once the compiling commands have be executed, the object files Item.o, ShoppingList.o, and shop.o should have been created. To link the object files into an executable file named shop, run the following command. The -o option sets the name for the executable to whatever follows it on the command-line.
$ g++ -g -Wall -o shop Item.o ShoppingList.o shop.o
Once the linking command has run, the executable file shop should have been created. To run the program, you must simply enter the name of the executable file on the command-line followed by any arguments that the executable needs. The following is an example of how to execute shop.
$ shop MEIJERS.TXT
To understand why headers need protection from multiple inclusions, consider the following code slice.
#include "MyHdr.h" #include "MyHdr.h"
Imagine that the above code appears in a source file MySrc.cxx, and
you enter the command g++ MySrc.cxx. The first thing that happens
is that the preprocessor replaces each #include line with the contents
of MyHdr.h. When the preprocessor is done, the file (with replaced #includes)
is compiled. Of course, the compilation fails due to multiple definitions of
whatever was in MyHdr.h.
This may not seem like a big problem to you, because MyHdr.h was so
obviously included twice in the above example, but often multiple inclusions
are not nearly as easy to see. In even moderately large software projects, there
are often headers included in headers included in still other headers (and so
on). The result is that when you #include a given header in a file,
you have no idea what other headers are being included with it, and you might
have to go to a lot of trouble to find out. The good news is that there is a
mechanism to prevent headers, which are mutiply included from being multiply
compiled.
To prevent a header file from being multiply compiled, you simply need to add 2 lines at the beginning of the header and 1 at the end of it. The following is an example of MyHdr.h that's been protected from multiple inclusions.
#ifndef MYHDR_H #define MYHDR_H ... #endif
In the above code, MYHDR_H is a symbolic constant. The first line
begins a conditional compilation block that can be read, "if MYHDR_H
is not defined, then compile the following." The second line defines MYHDR_H.
The final line marks the end of the conditional compilation block.
Now apply this to the MySrc.cxx example. The first time that the compiler
encounters the MyHdr.h code, MYHDR_H won't be defined so
the code will be compiled and MYHDR_H will become defined. Each
subsequent time that the compiler encounters MyHdr.h code, since MYHDR_H
has already been defined, it will skip over the MyHdr.h code.
Finally, you should know that all the C/C++ standard headers have been protected from multiple inclusions.