The C Pre-Processor * Review: Compilation Steps * What Does the C Pre-Processor Do? * Including Files * Playing with Macros * CPP Conditionals * Standard Header File Format * The Preprocessor and the Command Line * Some Great Preprocessor Hacks Compilation: From .c files to executable * Step one: Preprocess * Really simple translation of text: Produces C source code * Step two: Translate from C to assembly * Step three: Assemble the assembly into relocatable object code * Step four: Link the object code (with libraries) into an executable The C Preprocessor generally has directives that begin with # * Textual substitution / Macros #define OLDTEXT REPLACEMENT #define OLDTEXT(PARAMS) REPLACEMENT #undef MACRO * #if, #ifdef, #ifndef - Conditional text * #include STUFF * Can be .h * Can be .c Playing with include * #include includes the *header* file, which provides * types * extern stuff for functions * The LINKER joins in the other functions. * Example * Source int main (void) { printf ("Hello world.\n"); return 0; } // main * Compiling to object $ nm example1.o 0000000000000000 T main U puts * Naming executable (Do it yourself) * Morals: * For many libraries, we do dynamically loaded libraries (hopefully nicer than Windows DLL) * For some libraries, only the necessary stuff actually gets linked directly into the program. * Big .h files should affect processing time slightly (has to read in all of the function definitions) but not executable size. * Experiment suggests otherwise: statically linked is 100x the size (agh!) Note: Standard form for .h files #ifndef __MYNAME_H__ #define __MYNAME_H__ ... #endif // __MYNAME_H__ * Because it avoids code duplication if someone accidentally includes the same .h file twice. On to Macros #define NAME(PARAMS) REPLACEMENT Example int maxwell (int x, int y) { return x > y ? x : y; } #define MAXWELL(X,Y) X > Y ? X : Y * Why do macros exist? * Potentially faster: Function calls are expensive. You need a JUMP and a RETURN and lots of stack manipulation. + Small experiment: About 1.5 times as many lines in main, plus the lines in maxwell. * A way to do constants const int MAX_SIZE = 128 vs #define MAX_SIZE 128 * Modern macros can do things that functions cannot do - Textual stuff #define PREFIX(foo,bar) foo ## bar