The document discusses C preprocessing and macros. C preprocessing involves a preprocessor pass before compilation that handles file inclusion, conditional compilation, and macro definitions. Macros allow text substitution and are defined using the #define directive. Care must be taken when using macros as they do simple text replacement without type checking. Common preprocessor directives include #include, #ifdef, #if, #define, #undef.
The document discusses C preprocessing and macros. C preprocessing involves a preprocessor pass before compilation that handles file inclusion, conditional compilation, and macro definitions. Macros allow text substitution and are defined using the #define directive. Care must be taken when using macros as they do simple text replacement without type checking. Common preprocessor directives include #include, #ifdef, #if, #define, #undef.
CS 217 2 C Preprocessor Invoked automatically by the C compiler o 1 st pass: invokes C preprocessor o 2 nd pass: invokes compiler on the resulting C code Manually invoke C preprocessor gcc E foo.c Preprocessor Compiler Modified C program C program Object code 3 Preprocessor Directives Three kinds of directives o File inclusion #include o Conditional compilation #if, #ifdef, #ifndef, #elif, #else, #endif o Macros #define Rules o Always starts with a line with # o Can appear anywhere in a program o Comments may appear on the same line o Takes one line unless explicitly continue #def i ne MAX_CHARS 300 / * max f i l e name si ze */ #def i ne MAX_FI LES \ 100 4 File Inclusion Why? o Allow a program or a modules implementation to use certain interfaces An interface or a header file contains declarations for a module o Name of the header file should end in .h User-define header files ... #include mydefs.h System header files: < ... > #include <stdio.h> 5 Conditional Compilation Why? o One source for many platforms or many cases o Need to have special source for specific situations Conditional compilation #ifdef name #ifndef name #if expr #elif expr #else #endif Removing macro definitions #undef plusone #ifndef FOO_H #define FOO_H #ifdef WINDOWS_OS #include <windows.h> #elif LINUX_OS #include <linux.h> #endif . . . #endif gcc -DWINDOWS_OS foo.c 6 Another Example Conditionally compile debugging code ... if (some expr) { some code #ifdef DEBUG printf(this path taken\n ); #endif } else some other code; 7 Macros Provide parameterized text substitution Why? o The code may be slightly faster o No type checking Macro definition #define MAXLINE 120 #define lower(c) ((c)-`A+a) Macro replacement char buf[MAXLINE+1]; becomes char buf[120+1]; c = lower(buf[i]); becomes c = ((buf[i])-`A+a); 8 Macros: Use ( and ) Always parenthesize macro parameters in definition #define plusone(x) x+1 i = 3*plusone(2); becomes i = 3*2+1 #define plusone(x) ((x)+1) i = 3*plusone(2); becomes i = 3*((2)+1) 9 Macros: Careful about Side-Effects ++and operators create side effects Always avoid side-effects in parameters passed to macros #define max(a, b) ((a)>(b)?(a):(b)) y = max(i++, j++) becomes y = ((i++)>(j++)?(i++):(j++)); Question o What data type can we use in the macro max 10 More on Macros: # Operator #in the macro converts an argument into a string literal #define PRINT_INT(x) printf( #x = %d\n, x) ... PRINT_INT( x * y ); ... will become ... printf( x * y = %d\n, x*y); ... Question o We now have foobar in printf, what does this mean? 11 More on Macros: ## Operator You may never need to use this ##pastes two tokens into one Example #define GENERIC_MAX(type) \ type type##_max(type x, type y) \ { return x > y ? x : y }; GENERIC_MAX(float) becomes float float_max(float x, float y) { return x > y ? x : y }; 12 More on Macros: #error Let the preprocessor print out an error message #error message Example #if defined(WINDOWS) ... #elif defined(LINUX) ... #elif defined(MAC_OS_X) ... #else #error no OS specified #endif 13 More on Macros: #line Redefine the line number for the compiler #l i ne n or #l i ne n f i l e Example f oo. c: % gcc foo.c % bar.c: In function `main': % bar.c:101: `i' undeclared (first use in this function) main() { #line 101 bar.c i++; } 14 Some General Properties A macro may contain another macro o Preprocessor will rescan to replace o How many times does the preprocessor rescan? A macro definition is in effect until the end of the file A macro may not be defined twice You can use #undefto undefine a macro 15 Summary Preprocessing allows programmers to modify C source code automatically o File inculcation o Conditional compilation o Macros Macros are sometimes useful, but you need to be careful o Make sure that you remember the rules o Must use parentheses for the arguments o Avoid side effects