BTCS 1223_Chap8_Preprocessor

download BTCS 1223_Chap8_Preprocessor

of 39

Transcript of BTCS 1223_Chap8_Preprocessor

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    1/39

    BTCS 1223: A DVANCED

    P ROGRAMMING :

    C HAPTER 8: C P REPROCESSOR

    Mohd Saad Bin Hamid

    Semester 2 : 2011/2012

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    2/39

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    3/39

    Introduction The C preprocessor executes before a program is

    compiled. Some actions it performs are the inclusion of other

    files in the file being compiled, definition of

    symbolic constants and macros , conditionalcompilation of program code and conditionalexecution of preprocessor directives .

    Preprocessor directives begin with # and only white-space characters and comments may appear before apreprocessor directive on a line.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    4/39

    #include Preprocessor Directive The #include preprocessor directive has been used

    throughout this text. The #include directive causes a copy of a specified file

    to be included in place of the directive. The two forms of the #include directive are:

    #include#include#include#include #include#include#include#include "filename""filename""filename""filename"

    The difference between these is the location thepreprocessor begins searches for the file to be included.

    If the file name is enclosed in quotes, the preprocessorstarts searches in the same directory as the file beingcompiled for the file to be included (and may search otherlocations, too).

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    5/39

    #include Preprocessor Directive This method is normally used to include

    programmer-defined headers. If the file name is enclosed in angle brackets ( < and

    >)used for standard library headers the search isperformed in an implementation-dependent manner,normally through predesignated compiler andsystem directories.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    6/39

    #include Preprocessor Directive The #include directive is used to include standard

    library headers such as stdio.h and stdlib.h(see Fig. 5.6) and with programs consisting ofseveral source files that are to be compiled together.

    A header containing declarations common to theseparate program files is often created and includedin the file.

    Examples of such declarations are structure andunion declarations, enumerations and functionprototypes.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    7/39

    #define Preprocessor Directive:Symbolic Constants

    The #define directive creates symbolic

    constantsconstants represented as symbolsandmacros operations defined as symbols.

    The #define directive format is #define#define#define#define identifier identifier identifier identifier replacement replacement replacement replacement- -- -text text text text

    When this line appears in a file, all subsequentoccurrences of identifier that do not appear in string

    literals will be replaced by replacement-textautomatically before the program is compiled.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    8/39

    #define Preprocessor Directive: SymbolicConstants (Cont.) For example,

    #define#define#define#define PI 3.14159PI 3.14159PI 3.14159PI 3.14159

    replaces all subsequent occurrences of the symbolicconstant PI with the numeric constant 3.14159 .

    Symbolic constants enable you to create a name fora constant and use the name throughout the program.

    If the constant needs to be modified throughout theprogram, it can be modified once in the #definedirective.

    When the program is recompiled, all occurrences ofthe constant in the program will be modifiedaccordingly.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    9/39

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    10/39

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    11/39

    #define Preprocessor Directive: Macros A macro is an identifier defined in a #define

    preprocessor directive. As with symbolic constants, the macro-identifier is

    replaced in the program with the replacement-text beforethe program is compiled.

    Macros may be defined with or without arguments . A macro without arguments is processed like a symbolic

    constant.

    In a macro with arguments , the arguments are substitutedin the replacement text, then the macro is expanded i.e.,the replacement-text replaces the identifier and argumentlist in the program.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    12/39

    #define Preprocessor Directive: Macros(Cont.)

    [ Note: A symbolic constant is a type of macro.]

    Consider the following macro definition with oneargument for the area of a circle:

    #define#define#define#define CIRC ! R!CIRC ! R!CIRC ! R!CIRC ! R! $ % & $ $$ % & $ $$ % & $ $$ % & $ $ PIPIPIPI & ' $ % & '& ' $ % & '& ' $ % & '& ' $ % & '

    $ % & &$ % & &$ % & &$ % & & Wherever CIRC ! R! $(& appears in the file,

    the value of ( is substituted for %in the

    replacement-text, the symbolic constant PI isreplaced by its value (defined previously) and themacro is expanded in the program.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    13/39

    #define Preprocessor Directive: Macros(Cont.)

    For example, the statement a)ea = CIRC ! R!CIRC ! R!CIRC ! R!CIRC ! R! $$$$ 4444 &*&*&*&*

    is expanded to a)ea = $ $ 3.141593.141593.141593.14159 & ' $& ' $& ' $& ' $ 4444 & ' $& ' $& ' $& ' $ 4444 & &*& &*& &*& &*

    and the value of the expression is evaluated andassigned to variable a)ea .

    The parentheses around each %in the replacementtext force the proper order of evaluation when themacro argument is an expression.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    14/39

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    15/39

    #define Preprocessor Directive: Macros(Cont.)

    If the parentheses are omitted, the macro expansion

    is a)ea = 3.141593.141593.141593.14159 ' c + ,,, , ' c + ,,, , *

    which evaluates incorrectly as

    a)ea = $ 3.141593.141593.141593.14159 ' c & + $ ,,, , ' c & + ,,, , *because of the rules of operator precedence.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    16/39

    #define Preprocessor Directive: Macros(Cont.)

    Macro CIRC ! R! could be defined as a

    function. Function ci)cle )ea

    doubledoubledoubledouble ci)cle )ea$ci)cle )ea$ci)cle )ea$ci)cle )ea$ doubledoubledoubledouble % &% &% &% &----

    )etu)n)etu)n)etu)n)etu)n 3.141593.141593.141593.14159 ' % ' %*' % ' %*' % ' %*' % ' %*

    performs the same calculation as macro

    CIRC ! R! , but the overhead of a function callis associated with function ci)cle )ea .

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    17/39

    #define Preprocessor Directive: Macros(Cont.)

    The advantages of macro CIRC ! R! are that

    macros insert code directly in the programavoiding function call overheadand the programremains readable because the CIRC ! R!

    calculation is defined separately and namedmeaningfully. A disadvantage is that its argument is evaluated

    twice.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    18/39

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    19/39

    #define Preprocessor Directive: Macros(Cont.) The following is a macro definition with two arguments

    for the area of a rectangle: #define#define#define#define R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R! $ %2 ( & $ $ % & ' $ ( & & Wherever R!C/ 0 ! R! $%2 (& appears in the

    program, the values of %and ( are substituted in themacro replacement text and the macro is expanded inplace of the macro name.

    For example, the statement )ect )ea = R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R! $ a + 44442 b + &*

    is expanded to )ect )ea = $ $ a + 4444 & ' $ b + & &*

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    20/39

    #define Preprocessor Directive: Macros(Cont.) The value of the expression is evaluated and

    assigned to variable )ect )ea . The replacement text for a macro or symbolicconstant is normally any text on the line after theidentifier in the #define directive.

    If the replacement text for a macro or symbolicconstant is longer than the remainder of the line, abackslash (\ ) must be placed at the end of the line,indicating that the replacement text continues on thenext line.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    21/39

    #define Preprocessor Directive: Macros(Cont.) Symbolic constants and macros can be discarded by

    using the #undef preprocessor directive . Directive #undef undefines a symbolic constant

    or macro name. The scope of a symbolic constant or macro is from

    its definition until it is undefined with #undef , oruntil the end of the file. Once undefined, a name can be redefined with

    #define . Functions in the standard library sometimes are

    defined as macros based on other library functions.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    22/39

    #define Preprocessor Directive: Macros(Cont.) A macro commonly defined in the stdio.h header is

    #define#define#define#define etcha)$& etc$ stdin &etcha)$& etc$ stdin &etcha)$& etc$ stdin &etcha)$& etc$ stdin & The macro definition of etcha) uses function etc

    to get one character from the standard input stream.

    Function utcha) of the stdio.h header and thecharacter handling functions of the ct( e.h headeroften are implemented as macros as well.

    Expressions with side effects (i.e., variable values aremodified) should not be passed to a macro becausemacro arguments may be evaluated more than once.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    23/39

    Conditional Compilation Conditional compilation enables you to control the

    execution of preprocessor directives and thecompilation of program code. Each of the conditional preprocessor directives

    evaluates a constant integer expression. Cast expressions, si6eof expressions and

    enumeration constants cannot be evaluated inpreprocessor directives.

    The conditional preprocessor construct is much likethe if selection statement.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    24/39

    Conditional Compilation (Cont.) Consider the following preprocessor code:

    #if#if#if#if 7defined$7defined$7defined$7defined$ 8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/ &&&define#define#define#define 8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/

    #endif#endif#endif#endif

    These directives determine if 8 C:0;/ 0/ is defined.

    The expression defined$ 8 C:0;/ 0/& evaluatesto 1 if 8 C:0;/ 0/ is defined; otherwise.

    If the result is , 7defined$8 C:0;/ 0/& evaluates

    to 1 and 8 C:0;/ 0/ is defined. Otherwise, the #define directive is skipped.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    25/39

    Conditional Compilation (Cont.) Every #if construct ends with #endif .

    Directives #ifdef and #ifndef are shorthand for #ifdefined$ name & and #if 7defined$ name &. A multiple-part conditional preprocessor construct may be

    tested by using the #elif (the equivalent of else if inan if statement) and the #else (the equivalent of elsein an if statement) directives.

    These directives are frequently used to prevent header filesfrom being included multiple times in the same source file.

    We use this technique extensively in the C++ part of thisbook.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    26/39

    Conditional Compilation (Cont.) During program development, it is often helpful to

    comment out portions of code to prevent it frombeing compiled.

    If the code contains comments, ' and ' cannot beused to accomplish this task.

    Instead, you can use the following preprocessorconstruct: #if#if#if#if

    code prevented from compiling code prevented from compiling code prevented from compiling code prevented from compiling #endif #endif #endif #endif

    To enable the code to be compiled, replace the inthe preceding construct with 1 .

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    27/39

    Conditional Compilation (Cont.) Conditional compilation is commonly used as a debugging

    aid. Many C implementations provide debuggers , whichprovide much more powerful features than conditionalcompilation.

    If a debugger is not available, )intf statements areoften used to print variable values and to confirm the flowof control.

    These )intf statements can be enclosed in conditionalpreprocessor directives so the statements are onlycompiled while the debugging process is not completed.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    28/39

    Conditional Compilation (Cont.) For example,

    #ifdef#ifdef#ifdef#ifdef !?@!?@!?@!?@)intf$)intf$)intf$)intf$ "Aa)iable % = Bd"Aa)iable % = Bd"Aa)iable % = Bd"Aa)iable % = Bd n"n"n"n" 2 % &*2 % &*2 % &*2 % &*#endif#endif#endif#endif

    causes a )intf statement to be compiled in theprogram if the symbolic constant !?@ has beendefined ( #define !?@ ) before directive#ifdef !?@ .

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    29/39

    Conditional Compilation (Cont.) When debugging is completed, the #define

    directive is removed from the source file (orcommented out) and the )intf statementsinserted for debugging purposes are ignored during

    compilation. In larger programs, it may be desirable to define

    several different symbolic constants that control the

    conditional compilation in separate sections of thesource file.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    30/39

    #e))o) and # )a ma PreprocessorDirectives The #error directive

    #e))o)#e))o)#e))o)#e))o) tokens tokens tokens tokens

    prints an implementation-dependent message including thetokens specified in the directive.

    The tokens are sequences of characters separated byspaces.

    For example, #e))o)#e))o)#e))o)#e))o) 1111 DDDD :ut of )an e e))o):ut of )an e e))o):ut of )an e e))o):ut of )an e e))o)

    contains 6 tokens. When a #e))o) directive is processed on some systems,

    the tokens in the directive are displayed as an errormessage, preprocessing stops and the program does notcompile.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    31/39

    #e))o) and # )a ma PreprocessorDirectives (Cont.) The #pragma directive

    # )a ma# )a ma# )a ma# )a ma tokens tokens tokens tokens causes an implementation-defined action.

    A pragma not recognized by the implementation is

    ignored.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    32/39

    Line Numbers The #line preprocessor directive causes the

    subsequent source code lines to be renumberedstarting with the specified constant integer value. The directive

    #line#line#line#line 1111starts line numbering from 1 beginning with thenext source code line.

    A file name can be included in the #line directive.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    33/39

    Line Numbers (Cont.) The directive

    #line#line#line#line 1 "file1.c"1 "file1.c"1 "file1.c"1 "file1.c"

    indicates that lines are numbered from 1beginning with the next source code line and that thename of the file for the purpose of any compilermessages is "file1.c" .

    The directive normally is used to help make themessages produced by syntax errors and compiler

    warnings more meaningful. The line numbers do not appear in the source file.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    34/39

    Predefined Symbolic Constants Standard C provides predefined symbolic constants,

    several of which are shown in Fig. 13.1. The identifiers for each of the predefined symbolic

    constants begin and end with two underscores.

    These identifiers and the defined identifier (usedin Section 13.5) cannot be used in #define or#undef directives.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    35/39

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

    macro value

    __LINE__Integer value re resenting the current line in the source code !ile"eing com iled#

    __$ILE__% string literal containing the resumed name o! the source !ile

    "eing com iled#

    __&%'E__% string literal in the !orm (Mmm dd ))))( containing the date in*hich the com ilation rocess "egan#

    __'IME__% string literal in the !orm (hh:mm:ss( containing the time at

    *hich the com ilation rocess "egan#

    __c lus lus

    %n integer value# %ll +,, com ilers have this constant de!ined tosome value# I! the com iler is !ull) com liant *ith the +,,standard its value is e-ual or greater than 1.. 11L de ending on

    the version o! the standard the) com l)#

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    36/39

    Assertions The assert macrodefined in the

    headertests the value of an expression . If the value of the expression is false ( ), asse)t

    prints an error message and calls function abort(of the general utilities library ) toterminate program execution.

    This is a useful debugging tool for testing if avariable has a correct value.

    For example, suppose variable %should never belarger than 1 in a program.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    37/39

    Assertions (Cont.) An assertion may be used to test the value of %and

    print an error message if the value of %is incorrect. The statement would be

    asse)t$ %

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    38/39

    Assertions (Cont.) You may then concentrate on this area of the code to

    find the error. If the symbolic constant 0 !?@ is defined,

    subsequent assertions will be ignored.

    Thus, when assertions are no longer needed, the line #define#define#define#define 0 !?@0 !?@0 !?@0 !?@

    is inserted in the program file rather than deleting

    each assertion manually.

    1992-2010 by Pearson Education,Inc. All Rights Reserved.

  • 8/13/2019 BTCS 1223_Chap8_Preprocessor

    39/39

    1992-2010 by Pearson Education,Inc. All Rights Reserved.