Compilers
A compiler translates source code
directly into assembly language or machine instructions. The eventual end
product is a file or files containing machine code. This is an involved process,
and usually takes several steps. The transition from writing code to executing
code is significantly longer with a compiler.
Depending on the acumen of the compiler
writer, programs generated by a compiler tend to require much less space to run,
and they run much more quickly. Although size and speed are probably the most
often cited reasons for using a compiler, in many situations they aren’t
the most important reasons. Some languages (such as C) are designed to allow
pieces of a program to be compiled independently. These pieces are eventually
combined into a final executable program by a tool called the
linker. This process is called separate
compilation.
Separate compilation has many benefits. A
program that, taken all at once, would exceed the limits of the compiler or the
compiling environment can be compiled in pieces. Programs can be built and
tested one piece at a time. Once a piece is working, it can be saved and treated
as a building block. Collections of tested and working pieces can be combined
into libraries for use by other programmers. As
each piece is created, the complexity of the other pieces is hidden. All these
features support the creation of large
programs[26].
Compiler debugging
features have improved significantly over time. Early compilers only generated
machine code, and the programmer inserted print statements to see what was going
on. This is not always effective. Modern compilers can insert information about
the source code into the executable program. This information is used by
powerful source-level debuggers to show exactly
what is happening in a program by tracing its progress through the source
code.
Some compilers tackle the
compilation-speed problem by performing in-memory
compilation. Most compilers work with files, reading and writing them in
each step of the compilation process. In-memory compilers keep the compiler
program in RAM. For small programs, this can seem as responsive as an
interpreter.