Compile, Link, and Execute
Traditionally, a C or a C++ program consists of a number of source files that are individually compiled into
object files. These object files are then linked together to produce the executable form of the program.
Each separately compiled program fragment must contain enough information to allow it to be linked
together with other program fragments. Most language rules are checked by the compiler as it compiles an
individual source file (translation unit). The linker checks to ensure that names are used consistently in different
compilation units and that every name used actually refers to something that has been properly
defined. The typical C++ runtime environment performs few checks on the executing code. A programmer
who wants run-time checking must provide the tests as part of the source code.
C++ interpreters and dynamic linkers modify this picture only slightly by postponing some checks until
the first use of a code fragment.
For example, I might write a simple factorial program and represent it as a separate source file f a c t .c :
/ / file fact.c:
#i n c l u d e "f a c t .h "
l o n g f a c t (l o n g f ) // recursive factorial
{
i f (f >1 )
r e t u r n f *f a c t (f -1 );
e l s e
r e t u r n 1 ;
}
A separately compiled program fragment has an interface consisting of the minimal information needed to
use it. For this simple f a c t .c program fragment, the interface consists of the declaration of f a c t () stored in
a file f a c t .h :
/ / file fact.h:
l o n g f a c t (l o n g );
The interface is #i n c l u d e d in each translation unit that uses it. I also tend to #i n c l u d e an interface into the
translation unit that defines it to give the compiler a chance to diagnose inconsistencies early.
The f a c t () function can now be used like this:
/ / file main.c:
#i n c l u d e "f a c t .h "
#i n c l u d e <i o s t r e a m >
i n t m a i n ()
{
s t d :: c o u t << "f a c t o r i a l (7 ) i s " << f a c t (7 ) << ´\ n ´;
r e t u r n 0 ;
}
No comments:
Post a Comment