Chapter 13 - The Preprocessor: Outline
Chapter 13 - The Preprocessor: Outline
Outline
13.1 Introduction
13.2 The #include Preprocessor Directive
13.3 The #define Preprocessor Directive: Symbolic Constants
13.4 The #define Preprocessor Directive: Macros
13.5 Conditional Compilation
13.6 The #error and #pragma Preprocessor Directives
13.7 The # and ## Operators
13.8 Line Numbers
13.9 Predefined Symbolic Constants
13.10 Assertions
• Preprocessing
– Occurs before a program is compiled
– Inclusion of other files
– Definition of symbolic constants and macros
– Conditional compilation of program code
– Conditional execution of preprocessor directives
• Format of preprocessor directives
– Lines begin with #
– Only whitespace characters before directives on a line
• Used for
– Loading header files (#include <iostream>)
– Programs with multiple source files to be compiled together
– Header file - has common declarations and definitions (classes, structures,
function prototypes)
• #include statement in each file
• Symbolic constants
– When program compiled, all occurrences of symbolic constant replaced
with replacement text
• Format
#define identifier replacement-text
– Example: #define PI 3.14159
– everything to right of identifier replaces text
#define PI = 3.14159
• replaces "PI" with " = 3.14159", probably results in an error
– Cannot redefine symbolic constants with more #define statements
• Macro
– Operation defined in #define
– Macro without arguments: treated like a symbolic constant
– Macro with arguments: arguments substituted for replacement text,
macro expanded
– Performs a text substitution - no data type checking
Example:
#define CIRCLE_AREA( x ) ( PI * ( x ) * ( x ) )
area = CIRCLE_AREA( 4 );
becomes
area = ( 3.14159 * ( 4 ) * ( 4 ) );
• Multiple arguments
#define RECTANGLE_AREA( x, y ) ( ( x ) * ( y ) )
rectArea = RECTANGLE_AREA( a + 4, b + 7 );
becomes
rectArea = ( ( a + 4 ) * ( b + 7 ) );
• Conditional compilation
– Control preprocessor directives and compilation
– Cast expressions, sizeof, enumeration constants cannot be
evaluated
• Structure similar to if
#if !defined( NULL )
#define NULL 0
#endif
– Determines if symbolic constant NULL defined
• If NULL is defined, defined(NULL) evaluates to 1
• If NULL not defined, defines NULL as 0
– Every #if ends with #endif
– #ifdef short for #if defined(name)
– #ifndef short for #if !defined(name)
• Other statements
#elif - equivalent of else if in an if structure
#else - equivalent of else in an if structure
• Debugging
#define DEBUG 1
#ifdef DEBUG
cerr << "Variable x = " << x << endl;
#endif
• #pragma tokens
– Implementation defined action (consult compiler documentation)
– Pragmas not recognized by compiler are ignored
•#
– Replacement text token converted to string with quotes
#define HELLO( x ) cout << "Hello, " #x << endl;
HELLO(John) Notice #
becomes
cout << "Hello, " "John" << endl;
• Strings separated by whitespace are concatenated when using cout
• ##
– Concatenates two tokens
#define TOKENCONCAT( x, y ) x ## y
TOKENCONCAT( O, K )
becomes
OK
• #line
– renumbers subsequent code lines, starting with integer value
– file name can be included
• assert macro
– Header <assert.h>
– Tests value of an expression
– If 0 (false) prints error message and calls abort
assert( x <= 10 );
• If NDEBUG defined...
– All subsequent assert statements ignored
– #define NDEBUG