90 likes | 235 Views
CSC 253. Lecture 6. Declarations vs. Definitions. Why do we separate declarations from definitions? You can’t call a function unless it’s been previously declared; suppose f calls g and g calls f … You can compile with the declarations even if the code has been previously compiled.
E N D
CSC 253 Lecture 6
Declarations vs. Definitions • Why do we separate declarations from definitions? • You can’t call a function unless it’s been previously declared; suppose f calls g and g calls f … • You can compile with the declarations even if the code has been previously compiled. • You might not want them to unless they bought a source license. • What is the rule for placing declarations and definitions? • What is “module-based programming” in C? • Dividing functionality of the program into set of paired .h and .c files.
Our int_math module • Let’s define a file that contains two functions • pow(int base, int exp) • fact(int n) • The first function is essentially the same as we wrote in the 3rd week. • Let’s start with the header file.
Our int_math.h • What idiom do we need to use at the beginning of the file? • Let’s write the rest of the code …
Out int_math.c • Let’s check parameters for validity … • Let’s code fact() recursively. • Suppose we compile int_math.c; what will happen?
Separate Compilation • We can compile int_math.c even without writing a main program. • We just use the -c switch on our call to gcc • This produces an object file that can be used later.
The Main Program • Now let’s write the main program … • (exercise) • We can run the program by listing our source file, along with the precompiled object file. • We can also compile both files together …
Here’s the shell commands we invoked • # Suppose we compile int_math.c without a flag that says not to link ... • lec6% gcc int_math.c • Undefined first referenced • symbol in file • main /afs/bp.ncsu.edu/contrib/gcc281/lib/gcc-lib/sparc-sun-\ • solaris2.8/2.8.1/crt1.o • ld: fatal: Symbol referencing errors. No output written to a.out • # To avoid this error, we need to use a -c flag on the compile; that means "compile-only" • lec6% gcc -c int_math.c • # Let's see what file this created for us .. • lec6% ls -lt | head -5 • total 16 • -rw-r--r-- 1 efg ncsu 944 Sep 21 11:17 int_math.o • -rw-r--r-- 1 efg ncsu 300 Sep 21 11:15 int_math.c • -rw-r--r-- 1 efg ncsu 595 Sep 21 11:03 int_math.h • # Suppose we now compile (only) our main program • lec6% gcc our_main.c • Undefined first referenced • symbol in file • pow /var/tmp/cchBaadV1.o • fact /var/tmp/cchBaadV1.o • ld: fatal: Symbol referencing errors. No output written to a.out • # Oh, we need to tell the compiler about the code we already compiled ... • lec6% gcc our_main.c int_math.o • lec6% a.out • 7 to the 7th power is 823543. • 7! = 5040 • # Now lets "rm int_math.o" and see what happens ... • lec6% rm int_math.o
Here’s the last part of the commands … • lec6% gcc -pedantic-errors our_main.c int_math.o • gcc: int_math.o: No such file or directory • # So if the .o file isn't there, we need to compile the source again ... • lec6% gcc -pedantic-errors our_main.c int_math.c • lec6% a.out • 7 to the 7th power is 823543. • 7! = 5040 • # Or, we can name the binary file that the compile produces ... • lec6% gcc -pedantic-errors -o our_main our_main.c int_math.c • lec6% our_main • 7 to the 7th power is 823543. • 7! = 5040 • lec6%