When you type gcc …, there are three (conceptual) stages to "build" an executable. 1. Preprocessor -- remove comments; handle #define, #include, etc. Converts the code you wrote into messy code that does not have comments, or any preprocessor directives (#include, #define, #▒▒▒▒▒, …) CLEAN C CODE → UGLY C CODE 2. Compiler ------ takes one .c file at a time (after preprocessing) and converts to "object code" which is just each function in the file compiled into machine language. If you have multiple .C files, there will be multiple object files (.o files). With the way we compile, you won't see them. UGLY C CODE → UNUSABLE OBJECT FILES* (MACHINE LANGUAGE) * (usually plural) 3. Linker -------- Combine the object files (e.g., mintf.o, test_mintf.o) into one executable that you can run. UNUSABLE OBJECT FILES (MACHINE LANGUAGE) → RUNNABLE EXECUTABLE To call preprocessor directly from bash: $ /usr/bin/cpp j.c … or with some indenting… $ /usr/bin/cpp j.c | indent -kr … or with cleaned up output (this class only, obviously)… $ 264cpp j.c ### YOU WILL NEED THIS FOR DEBUGGING HW06 and HW07 ### ------------------------------------- For preprocessor macros: #define «NAME»(«PARAMETERS…») «REPLACMENT» Parenthesize entire replacement. Parenthesize each parameter. #define macros do not respect types or order of operations.