Sei sulla pagina 1di 37

PREPROCESSORS

a preprocessor is a program that processes its input data to produce output that is used as input to another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs li e compilers. The amount and ind of processing done depends on the nature of the preprocessor! some preprocessors are only capable of performing relati"ely simple te#tual substitutions and macro e#pansions, while others ha"e the power of fully$fledged programming languages. % common e#ample from computer programming is the processing performed on source code before the ne#t step of compilation. &n some computer languages 'e.g., C and P()& * there is a phase of translation nown as preprocessing.

Lexical preprocessors
(e#ical preprocessors are the lowest$le"el of preprocessors, insofar as they only require le#ical analysis, that is, they operate on the source te#t, prior to any parsing, by performing simple substitution of to eni+ed character sequences for other to eni+ed character sequences, according to user$defined rules. They typically perform macro substitution, te#tual inclusion of other files, and conditional compilation or inclusion.

[edit] C preprocessor
The most common e#ample of this is the C preprocessor, which ta es lines beginning with ,-, as directi"es. .ecause it nows nothing about the underlying language, its use has been critici+ed and many of its features built directly into other languages. /or e#ample, macros replaced with aggressi"e inlining and templates, includes with compile$time imports 'this requires the preser"ation of type information in the ob0ect code, ma ing this feature impossible to retrofit into a language*! conditional compilation is effecti"ely accomplished with if-then-else and dead code elimination in some languages.

[edit] Other lexical preprocessors


Other le#ical preprocessors include the general$purpose m1, most commonly used in cross$platform build systems such as autoconf, and 2E3%, an open source macro processor which operates on patterns of conte#t.

C preprocessor
The C preprocessor 'cpp* is the preprocessor for the C programming language. &n many C implementations, it is a separate program in"o ed by the compiler as the first part of translation. The preprocessor handles directi"es for source file inclusion '#include*, macro definitions '#define*, and conditional inclusion '#if*. The language of preprocessor directi"es is agnostic to the grammar of C, so the C preprocessor can also be used independently to process other types of files.

The transformations it ma es on its input form the first four of C,s so$called Phases of Translation. Though an implementation may choose to perform some or all phases simultaneously, it must beha"e as if it performed them one$by$one in order.

Contents
4hide5

6 Phases 7 &ncluding files 8 Conditional compilation 1 3acro definition and e#pansion o 1.6 Standard predefined positioning macros o 1.7 Precedence o 1.8 3ultiple lines o 1.1 3ultiple e"aluation of side effects o 1.9 To en concatenation o 1.: Semicolons 1.:.6 3ultiple statements o 1.; <uoting macro arguments 1.;.6 &ndirectly quoting macro arguments 1.;.7 .rainteaser o 1.= >ariadic macros o 1.? @$3acros o 1.6A Compiler$specific predefined macros 9 Bser$defined compilation errors and warnings : Compiler$specific preprocessor features o :.6 Constandard e#tensions ; %s a general$purpose preprocessor = See also ? References 6A E#ternal lin s

[edit] Phases
The following are the first four 'of eight* phases of translation specified in the C StandardD 6. Trigraph Replacement $ The preprocessor replaces trigraph sequences with the characters they represent. 7. (ine Splicing $ Physical source lines that are continued with escaped newline sequences are spliced to form logical lines. 8. To eni+ation $ The preprocessor brea s the result into preprocessing tokens and whitespace. &t replaces comments with whitespace.

1. 3acro E#pansion and Eirecti"e Fandling $ Preprocessing directi"e lines, including file inclusion and conditional compilation, are e#ecuted. The preprocessor simultaneously e#pands macros and, in the 6??? "ersion of the C standard, handles _Pragma operators.

[edit] Including files


The most common use of the preprocessor is to include another fileD
#include <stdio.h> int main (void) { printf("Hello return %$ &

!orld"#n")$

The preprocessor replaces the line #include <stdio.h> with the system header file of that name, which declares the printf() function among other things. 3ore precisely, the entire te#t of the file ,stdio.h, replaces the #include directi"e. This can also be written using double quotes, e.g. #include "stdio.h". &f the filename is enclosed within angle brac ets, the file is searched for in the standard compiler include paths. &f the filename is enclosed within double quotes, the search path is e#panded to include the current source directory. C compilers and programming en"ironments all ha"e a facility which allows the programmer to define where include files can be found. This can be introduced through a command line flag, which can be parameteri+ed using a ma efile, so that a different set of include files can be swapped in for different operating systems, for instance. .y con"ention, include files are gi"en a .h e#tension, and files not included by others are gi"en a .c e#tension. Fowe"er, there is no requirement that this be obser"ed. Occasionally you will see files with other e#tensions includedD files with a .def e#tension may denote files designed to be included multiple times, each time e#panding the same repetiti"e content! #include "icon.'(m" is li ely to refer to an @.3 image file 'which is at the same time a C source file*.
#include

often compels the use of #include guards or #pragma once to pre"ent double

inclusion.

[edit] Conditional compilation


The #if, #ifdef, #ifndef, #else, #elif and #endif directi"es can be used for conditional compilation.
#ifdef _)*+,- .. _)*+,- is defined (/ all )indo!s ,- and 01 (it compilers (ut not (/ others. #include <!indo!s.h>

#else #include <unistd.h> #endif #if 2345673 >8 print("trace message")$ #endif

Cote that comparison operations will only wor with integers


#if 2345673 88 print("trace #endif #if 2345673 >8 print("trace #endif "on" .. +69 :;;6)3< message")$ -.% .. +69 :;;6)3< message")$

Some compilers targeting Gindows define )*+,-, but all should define _)*+,-465 This allows code, including preprocessor commands, to compile only when targeting Gindows systems. %lternati"ely, the macro )*+,- could be defined implicitly by the compiler, or specified on the compiler,s command line, perhaps to control compilation of the program from a ma efile. The e#ample code tests if a macro _)*+,- is defined. &f it is, the file <!indo!s.h> is included, otherwise <unistd.h>. % more comple# e#ample might be something li e
#if "defined()*+,-) == defined(__>*+?),-__) ... #endif

Hou can also cause compilation to halt by using the -error directi"eD
#if 4@5A_2347*6+ 88 BC% # error B.C.% not supported #endif

[edit] Macro definition and expansion


There are two types of macros, object-like and function-like. Ob0ect$li e macros do not ta e parameters! function$li e macros do. The generic synta# for declaring an identifier as a macro of each type is, respecti"ely,
#define <identifier> <replacement toDen list> #define <identifier>(<parameter list>) <replacement toDen list>

Cote that the function-like macro declaration must not ha"e any whitespace between the identifier and the first, opening, parenthesis. &f whitespace is present, the macro will be interpreted as ob0ect$li e with e"erything starting from the first parenthesis added to the to en list.

Ghene"er the identifier appears in the source code it is replaced with the replacement to en list, which can be empty. /or an identifier declared to be a function$li e macro, it is only replaced when the following to en is also a left parenthesis that begins the argument list of the macro in"ocation. The e#act procedure followed for e#pansion of function$li e macros with arguments is subtle. Ob0ect$li e macros were con"entionally used as part of good programming practice to create symbolic names for constants, e.g.
#define P* ,.B1BEC

... instead of hard$coding those numbers throughout one,s code. %n alternati"e in both C and CII is to apply the const qualifier to a global "ariable. %n e#ample of a function$li e macro isD
#define 4:<96<3?(') ((') F EG.-CEGH)

This defines a radians to degrees con"ersion which can be written subsequently, e.g. 4:<96<3?(,1) or 4:<96<3? (,1). This is e#panded in$place, so the caller does not need to litter copies of the multiplication constant all o"er his code. The macro here is written as all uppercase to emphasi+e that it is a macro, not a compiled function.

[edit] Standard predefined positioning macros


Certain symbols are required to be defined by an implementation during preprocessing. These include __I*;3__ and __;*+3__, predefined by the preprocessor itself, which e#pand into the current file and line number. /or instance the followingD
.. de(ugging macros so !e can pin do!n message origin at a glance #define )H343794 "Jfile Ks line KdLM " #define )H343:4? __I*;3__ __;*+3__ #define <35@?P4*+9-(...) fprintf(stderr __2:_:4?7__) #define <35@?P4*+9(_fmt ...) <35@?P4*+9-()H343794 _fmt )H343:4? __2:_:4?7__) ..... <35@?P4*+9("he/ '8Kd#n" ')$

prints the "alue of ', preceded by the file and line number to the standard error stream, allowing quic access to which line the message was produced on. Cote that the )H343794 argument is concatenated with the string following it. The first C Standard specified that the macro __79<N__ be defined to 6 if the implementation conforms to the &SO Standard and A otherwise, and the macro __79<N_2347*6+__ defined as a numeric literal specifying the "ersion of the Standard supported by the implementation. Standard CII compilers support the __cplusplus macro. Compilers running in non$standard mode, with ad"anced or reduced language

features that may be conflicting with the essential standard, might not set these macros or should define others to e#hibit the differences. Other Standard macros include __<:93__ and __9*>3__, which e#pand to the date and time of translation respecti"ely The second edition of the C Standard, C??, added support for __func__, which contains the name of the function definition it is contained within, but due to preprocessor is agnostic to the grammar of C, this must be done in the compiler itself using a local "ariable of the function.

[edit] Precedence
Cote that the e#ample macro 4:<96<3?(') gi"en abo"e uses seemingly superfluous parentheses both around the argument and around the entire e#pression. Omitting either of these can lead to une#pected results. /or e#ampleD

3acro defined as

#define 4:<96<3?(') (' F EG.-CEGH)

will e#pand
4:<96<3?(a O ()

to
(a O ( F EG.-CEGH) 3acro defined as #define 4:<96<3?(') (') F EG.-CEGH

will e#pand
B . 4:<96<3?(a)

to
B . (a) F EG.-CEGH

neither of which gi"e the intended result.

[edit] Multiple lines


% macro can be e#tended o"er as many lines as required using a bac slash escape character at the end of each line. The macro ends after the first line which does not end in a bac slash.

The e#tent to which multi$line macros enhance or reduce the si+e and comple#ity of the source of a C program, or its readability and maintainability is open to debate 'there is no e#perimental e"idence on this issue*. Techniques such as @$3acros are occasionally used to address these potential issues.

[edit] Multiple evaluation of side effects


%nother e#ample of a function$li e macro isD
#define >*+(a () ((a)>(()P(()M(a))

Cotice the use of the ternary conditional PM operator. This illustrates one of the dangers of using function$li e macros. One of the arguments, a or b, will be e"aluated twice when this JfunctionJ is called. So, if the e#pression >*+(OOfirstnum secondnum) is e"aluated, then firstnum may be incremented twice, not once as would be e#pected. % safer way to achie"e the same would be to use a typeof$constructD
#define ma'(a () # ({ t/peof (a) _a 8 (a)$ # t/peof (() _( 8 (()$ # _a > _( P _a M _($ &)

This will cause the arguments to be e"aluated only once, and it will not be type$specific anymore. This construct is not legal %CS& C! both the t/peof eyword, and the construct of placing a compound statement within parentheses, are non$standard e#tensions implemented in the popular 2CB C compiler '2CC*. Sometimes, the problem can be a"oided with additional parameters li e soD
#define ma'(a ( t/pe ma') # do { # t/pe _a 8 (a)$ # t/pe _( 8 (()$ # ma' 8 _a > _( P _a M _($ # & !hile (%)

.ut this raises the comple#ity of both the macro and the calling code significantly. &f you are using 2CC, the general problem can also be sol"ed using a static inline function, which is as efficient as a #define. The inline function allows the compiler to chec )coerce parameter typesKin this particular e#ample this appears to be a disad"antage, since the ,ma#, function as shown wor s equally well with different parameter types, but in general ha"ing the type coercion is an ad"antage. Githin %CS& C, there is no reliable general solution to the issue of side$effects in macro arguments.

[edit] Token concatenation


To en concatenation, also called to en pasting, is one of the most subtle K and easy to abuse K features of the C macro preprocessor. Two arguments can be ,glued, together using ## preprocessor operator! this allows two to ens to be concatenated in the preprocessed code. This can be used to construct elaborate macros which act li e a crude "ersion of CII templates. /or instanceD
#define >AN:73(item id) # case idM # item##_##id 8 id$# (reaD s!itch(') { >AN:73(!idget -,)$ &

The line >AN:73(!idget -,)$ gets e#panded here into


case -,M !idget_-, 8 -,$ (reaD$

'The semicolon following the in"ocation of >AN:73 becomes the semicolon that completes the brea statement.* Only function$li e parameters can be pasted in a macro, and the parameters are not parsed for macro replacement first, so the following somewhat non$intuiti"e beha"ior occursD
enum { 6lder7mall 8 % +e!er;arge 8 B &$ #define 6lder +e!er #define 7mall ;arge #define _replace_B(6lder #define _replace_-(6lder 7mall) 6lder##7mall 7mall) _replace_B(6lder 7mall)

void printout( void ) { .. _replace_B( 6lder 7mall ) (ecomes 6lder7mall (not +e!er;arge) .. despite the #define calls a(ove. printf("NhecD BM Kd#n" _replace_B( 6lder 7mall ) )$ .. 9he parameters to _replace_- are su(stituted (efore the call .. to _replace_B so !e get +e!er;arge.

&

printf("NhecD -M Kd#n"

_replace_-( 6lder

7mall ) )$

results in
NhecD BM % NhecD -M B

[edit] Semicolons
One stylistic note about the abo"e macro is that the semicolon on the last line of the macro definition is omitted so that the macro loo s ,natural, when written. &t could be included in the macro definition, but then there would be lines in the code without semicolons at the end which would throw off the casual reader. Gorse, the user could be tempted to include semicolons anyway! in most cases this would be harmless 'an e#tra semicolon denotes an empty statement* but it would cause errors in control flow bloc sD
#define P4399A_P4*+9(msg) printf(msg)$ if (n < B%) P4399A_P4*+9("n is less than B%")$ else P4399A_P4*+9("n is at least B%")$

This e#pands to gi"e two statements L the intended printf and an empty statement L in each branch of the if)else construct, which will cause the compiler to gi"e an error message similar toD
errorM e'pected e'pression (efore QelseR

Kgcc 1.6.6 [edit] Multiple statements &nconsistent use of multiple$statement macros can result in unintended beha"iour. The code
#define N><7 # a 8 ($ # c 8 d if (var 88 B,) N><7$ else return$

will e#pand to
if (var 88 B,) a 8 ($ c 8 d$

else return$

which is a synta# error 'the else is lac ing a matching if*. The macro can be made safe by replacing the internal semicolon with the comma operator, since two operands connected by a comma form a single statement. The comma operator is the lowest precedence operator. &n particular, its precedence is lower than the assignment operator,s, so that a M b, c M d does not parse as a M 'b,c* M d. Therefore,
#define N><7 a 8 ( if (var 88 B,) N><7$ else return$ c 8 d

will e#pand to
if (var 88 B,) a 8 ( c 8 d$ else return$

The problem can also be fi#ed without using the comma operatorD
#define N><7 # do { # a 8 ($ # c 8 d$ # & !hile (%)

e#pands to
if (var 88 B,) do { a 8 ($ c 8 d$ & !hile (%)$ else return$

The do and !hile (%) are needed to allow the macro in"ocation to be followed by a semicolon! if they were omitted the resulting e#pansion would be
if (var 88 B,) { a 8 ($ c 8 d$ & $ else return$

The semicolon in the macro,s in"ocation abo"e becomes an empty statement, causing a synta# error at the else by pre"enting it matching up with the preceding if. % cleaner way, using the non$standard 2CB C compiler '2CC* compound statement within parentheses compiler e#tensionD
#define N><7 # ({ # a 8 ($ # c 8 d$ # &)

e#pands to
if (var 88 B,) ({ a 8 ($ c 8 d$ &)$ else return$

[edit] Quoting macro arguments


%lthough macro e#pansion does not occur within a quoted string, the te#t of the macro arguments can be quoted and treated as a string literal by using the J#J directi"e 'also nown as the JStringi+ing OperatorJ*. /or e#ample, with the macro
#define S@693>3(') #'

the code
printf("Ks#n" S@693>3(BO-))$

will e#pand to
printf("Ks#n" "BO-")$

This capability can be used with automatic string literal concatenation to ma e debugging macros. /or e#ample, the macro in
#define dumpme(' ') fmt) printf("KsMKuM Ks8" fmt __I*;3__ __;*+3__ #'

int some_function() { int foo$ .F Ja lot of complicated code goes hereL F. dumpme(foo "Kd")$ .F Jmore complicated code goes hereL F. &

would print the name of an e#pression and its "alue, along with the file name and the line number. [edit] Indirectly quoting macro arguments The J#J directi"e can also be used indirectly, in order to quote the J"alueJ of a macro instead of the name of that macro. /or e#ample, with the macroD
#define I66 (ar #define S@693>3_(') #' #define S@693>3(') S@693>3_(')

the code
printf("I668Ks#n" S@693>3(I66))$

will e#pand to
printf("I668Ks#n" "(ar")$

One common use for this technique is to con"ert the NN(&CENN macro to a string. EgD
S@693>3(__;*+3__)$

is con"erted toD
",1"

if NN(&CENN happens to ha"e the "alue 81 when <BOTE3E'* is called. On the other hand <BOTE3EN'NN(&CENN* will e#pand to JNN(&CENNJ [edit] Brainteaser The J#J directi"e is also used to sol"e the following preprocessor brainteaser 'in"ol"ing characters, as opposed to strings*D Eefine a macro, CF%R'*, which ta es a single input character @ in the source program te#t and con"erts it into the C$language character "alue of @! that is, such that
printf("Kc#n" printf("Kc#n" NH:4(a)) NH:4(())

yields
a (

SolutionD

#define NH:4(T)

#TJ%L

[edit] Variadic macros


3ain articleD >ariadic macro 3acros that can ta e a "arying number of arguments '"ariadic macros* are not allowed in C=?, but were introduced by a number of compilers and standardised in C??. >ariadic macros are particularly useful when writing wrappers to "ariable parameter number functions, such as printf, for e#ample when logging warnings and errors.

[edit] !Macros
One little$ nown usage pattern of the C preprocessor is nown as J@$3acrosJ.475485415 %n @$3acro is a header file 'commonly using a J.defJ e#tension instead of the traditional J.hJ* that contains a list of similar macro calls 'which can be referred to as Jcomponent macrosJ*. The include file is then referenced repeatedly in the following patternD '2i"en that the include file is J#macro.defJ and it contains a list of component macros of the style Jfoo'#, y, +*J*
#define foo(' / U) do7omething)ith(' #include "'macro.def" #undef foo / U)$

#define foo(' / U) do7omething3lse)ith(' #include "'macro.def" #undef foo (etc...)

U)$

The most common usage of @$3acros is to establish a list of C ob0ects and then automatically generate code for each of them. Some implementations also perform any #undefs they need inside the @$3acro, as opposed to e#pecting the caller to undefine them. Common sets of ob0ects are a set of global configuration settings, a set of members of a struct, a list of possible @3( tags for con"erting an @3( file to a quic ly$tra"ersable tree, or the body of an enum declaration! other lists are possible. Once the @$3acro has been processed to create the list of ob0ects, the component macros can be redefined to generate, for instance, accessor and)or mutator functions. Structure seriali+ing and deseriali+ing are also commonly done. Fere is an e#ample of an @$3acro that establishes a struct and automatically creates seriali+e)deseriali+e functionsD 'CoteD for simplicity, this e#ample doesn,t account for endianness or buffer o"erflows*

/ile star.defD
3TP:+<_3TP:+<_79:4_>3>534(' int) 3TP:+<_3TP:+<_79:4_>3>534(/ int) 3TP:+<_3TP:+<_79:4_>3>534(U int) 3TP:+<_3TP:+<_79:4_>3>534(radius dou(le) #undef 3TP:+<_3TP:+<_79:4_>3>534

/ile star_table.cD
t/pedef struct { #define 3TP:+<_3TP:+<_79:4_>3>534(mem(er #include "star.def" & star7truct$ t/pe) t/pe mem(er$

void serialiUe_star(const star7truct Fconst star unsigned char F(uffer) { #define 3TP:+<_3TP:+<_79:4_>3>534(mem(er t/pe) # memcp/((uffer V(star->mem(er) siUeof(star->mem(er))$ # (uffer O8 siUeof(star->mem(er)$ #include "star.def" & void deserialiUe_star(star7truct Fconst star const unsigned char F(uffer) { #define 3TP:+<_3TP:+<_79:4_>3>534(mem(er t/pe) # memcp/(V(star->mem(er) (uffer siUeof(star->mem(er))$ # (uffer O8 siUeof(star->mem(er)$ #include "star.def" &

Fandlers for indi"idual data types may be created and accessed using to en concatenation 'J##J* and quoting 'J#J* operators. /or e#ample, the following might be added to the abo"e codeD
#define print_int(val) printf("Kd" #define print_dou(le(val) printf("Kg" val) val)

void print_star(const star7truct Fconst star) { .F print_##t/pe !ill (e replaced !ith print_int or print_dou(le F. #define 3TP:+<_3TP:+<_79:4_>3>534(mem(er t/pe) # printf("KsM " #mem(er)$ # print_##t/pe(star->mem(er)$ # printf("#n")$ #include "star.def" &

Cote that in this e#ample you can also a"oid the creation of separate handler functions for each datatype in this e#ample by defining the print format for each supported type, with the additional benefit of reducing the e#pansion code produced by this header fileD
#define I64>:9_(t/pe) I64>:9_##t/pe #define I64>:9_int "Kd"

#define I64>:9_dou(le "Kg" void print_star(const star7truct Fconst star) { .F I64>:9_(t/pe) !ill (e replaced !ith I64>:9_int or I64>:9_dou(le F. #define 3TP:+<_3TP:+<_79:4_>3>534(mem(er t/pe) # printf("KsM " I64>:9_(t/pe) "#n" #mem(er star->mem(er)$ #include "star.def" &

The creation of a separate header file can be a"oided by creating a single macro containing what would be the contents of the file. /or instance, the abo"e file Jstar.defJ could be replaced with this macro at the beginning ofD /ile star_table.cD
#define 3TP:+<_79:4 # 3TP:+<_79:4_>3>534(' int) 3TP:+<_79:4_>3>534(/ int) 3TP:+<_79:4_>3>534(U int) 3TP:+<_79:4_>3>534(radius # # # dou(le)

and then all calls to #include "star.def" could be replaced with a simple 3TP:+<_79:4 statement. The rest of the abo"e file would becomeD
t/pedef struct { #define 3TP:+<_79:4_>3>534(mem(er 3TP:+<_79:4 #undef 3TP:+<_79:4_>3>534 & star7truct$ t/pe) t/pe mem(er$

void serialiUe_star(const star7truct Fconst star unsigned char F(uffer) { #define 3TP:+<_79:4_>3>534(mem(er t/pe) # memcp/((uffer V(star->mem(er) siUeof(star->mem(er))$ # (uffer O8 siUeof(star->mem(er)$ 3TP:+<_79:4 #undef 3TP:+<_79:4_>3>534 & void deserialiUe_star(star7truct Fconst star const unsigned char F(uffer) { #define 3TP:+<_79:4_>3>534(mem(er t/pe) # memcp/(V(star->mem(er) (uffer siUeof(star->mem(er))$ # (uffer O8 siUeof(star->mem(er)$ 3TP:+<_79:4 #undef 3TP:+<_79:4_>3>534 &

and the print handler could be added as well asD


#define print_int(val) printf("Kd" #define print_dou(le(val) printf("Kg" val) val)

void print_star(const star7truct Fconst star) { .F print_##t/pe !ill (e replaced !ith print_int or print_dou(le F. #define 3TP:+<_79:4_>3>534(mem(er t/pe) # printf("KsM " #mem(er)$ # print_##t/pe(star->mem(er)$ # printf("#n")$ 3TP:+<_79:4 #undef 3TP:+<_79:4_>3>534 &

or asD
#define I64>:9_(t/pe) I64>:9_##t/pe #define I64>:9_int "Kd" #define I64>:9_dou(le "Kg" void print_star(const star7truct Fconst star) { .F I64>:9_(t/pe) !ill (e replaced !ith I64>:9_int or I64>:9_dou(le F. #define 3TP:+<_79:4_>3>534(mem(er t/pe) # printf("KsM " I64>:9_(t/pe) "#n" #mem(er star->mem(er)$ 3TP:+<_79:4 #undef 3TP:+<_79:4_>3>534 &

% "ariant which a"oids needing to now the members of any e#panded sub$macros is to accept the operators as an argument to the list macroD /ile star_table.cD
.F ?eneric F. #define 794@N9_>3>534(mem(er

t/pe

dumm/) t/pe mem(er$

#define 734*:;*W3_>3>534(mem(er t/pe o(X (uffer) # memcp/((uffer V(o(X->mem(er) siUeof(o(X->mem(er))$ # (uffer O8 siUeof(o(X->mem(er)$ #define <3734*:;*W3_>3>534(mem(er t/pe o(X (uffer) # memcp/(V(o(X->mem(er) (uffer siUeof(o(X->mem(er))$ # (uffer O8 siUeof(o(X->mem(er)$ #define I64>:9_(t/pe) I64>:9_##t/pe #define I64>:9_int "Kd" #define I64>:9_dou(le "Kg" .F I64>:9_(t/pe) !ill (e replaced !ith I64>:9_int or I64>:9_dou(le F. #define P4*+9_>3>534(mem(er t/pe o(X) # printf("KsM " I64>:9_(t/pe) "#n" #mem(er o(X->mem(er)$ .F star7truct F. #define 3TP:+<_79:4(_ ...) #

_(' int _(/ int _(U int _(radius

__2:_:4?7__) # __2:_:4?7__) # __2:_:4?7__) # dou(le __2:_:4?7__) ) unsigned char

t/pedef struct { 3TP:+<_79:4(794@N9_>3>534 & star7truct$

void serialiUe_star(const star7truct Fconst star F(uffer) { 3TP:+<_79:4(734*:;*W3_>3>534 star (uffer) &

void deserialiUe_star(star7truct Fconst star const unsigned char F(uffer) { 3TP:+<_79:4(<3734*:;*W3_>3>534 star (uffer) & void print_star(const star7truct Fconst star) { 3TP:+<_79:4(P4*+9_>3>534 star) &

This approach can be dangerous in that the entire macro set is always interpreted as if it was on a single source line, which could encounter compiler limits with comple# component macros and)or long member lists.

[edit] Compiler!specific predefined macros


Compiler$specific predefined macros are usually listed in the compiler documentation, although this is often incomplete. The Pre$defined C)CII Compiler 3acros pro0ect lists J"arious pre$defined compiler macros that can be used to identify standards, compilers, operating systems, hardware architectures, and e"en basic run$time libraries at compile$ timeJ. Some compilers can be made to dump at least some of their useful predefined macros, for e#ampleD 2CB C Compiler
gcc -d> -3 - < .dev.null

FP$B@ ansi C compiler cc -v fred.c 'where fred.c is a simple test file* SCO OpenSer"er C compiler cc -## fred.c 'where fred.c is a simple test file* Sun Studio C)CII compiler cc -## fred.c 'where fred.c is a simple test file* &.3 %&@ @( C)CII compiler cc -Ysho!macros -3 fred.c 'where fred.c is a simple test file*

[edit] User-defined compilation errors and warnings


The #error directi"e inserts an error message into the compiler output.
#error "?aah""

This prints J2aahOJ in the compiler output and halts the computation at that point. This is e#tremely useful for determining whether a gi"en line is being compiled or not. &t is also useful if you ha"e a hea"ily parameteri+ed body of code and want to ma e sure a particular #define has been introduced from the ma efile, e.g.D
#ifdef )*+<6)7 ... .F )indo!s specific code F. #elif defined(@+*T) ... .F @ni' specific code F. #else #error ")hatZs /our operating s/stemP" #endif

%lthough the te#t following the #error directi"e does not ha"e to be quoted, it is good practice to do so. Otherwise, there may be problems with apostrophes and other characters that the preprocessor tries to interpret.

[edit] Compiler-specific preprocessor features


The #pragma directi"e is a compiler specific directi"e which compiler "endors may use for their own purposes. /or instance, a #pragma is often used to allow suppression of specific error messages, manage heap and stac debugging, etc. C?? introduced a few standard #pragma directi"es, ta ing the form #pragma 79<N [, which are used to control the floating$point implementation.

[edit] "onstandard extensions


3any implementations do not support trigraphs or do not replace them by default. 3ost implementations 'including e.g. the C$compilers by 2CB, &ntel, &.3, 3icrosoft4citation needed5 and %pple*4which?5 pro"ide a non$standard #!arning directi"e to print out a warning message in the compiler output, but not stop the compilation process. % typical use is to warn about the usage of some old code, which is now deprecated and only included for compatibility reasons, e.g.D little similarity to assertions used in programming. The synta# is described at 2CC Obsolete features. 2CC pro"ides 465 -includeNne#t for chaining headers of the same name. Ob0ecti"e$C preprocessors ha"e -import which is li e -include, but only includes the file once.

#!arning "<o not use :5N !hich is deprecated. @se TAW instead." Some uni# preprocessors traditionally pro"ided JassertionsJ, which ha"e

[edit] As a general-purpose preprocessor


Since the C preprocessor can be in"o ed independently to process files other than those containing to$be$compiled source code, it can also be used as a Jgeneral purpose preprocessorJ for other types of te#t processing. One particularly notable e#ample is the now$deprecated ima e system! more e#amples are listed at 2eneral purpose preprocessor. CPP does wor acceptably with most assembly languages. 2CB mentions assembly as one of the target languages among C, CII and Ob0ecti"e$C in the documentation of its implementation of the preprocessor. This requires that the assembler synta# not conflict with cpp,s synta#, which means no lines starting with - and that double quotes, which cpp interprets as string literals and thus ignores, don,t ha"e syntactical meaning other than that.

[edit] See also


C synta# 3a e Preprocessor

[edit]

eferences

6. ^ (ist of predefined %CS& C and 3icrosoft CII implementation macros. 7. ^ C Preprocessor Tric /or &mplementing Similar Eata Types 8. ^ 3eyers, Randy '3ay 7AA6*. JThe Cew CD @ 3acrosJ. Dr. Dobb's Journal. httpD))www.dd0.com)cpp)6=11A68=;. Retrie"ed 6 3ay 7AA=. 1. ^ .eal, Stephan '%ugust 7AA1*. Supermacros. httpD))wanderinghorse.net)computing)papers)-supermacros. Retrie"ed 7; October 7AA=.

[edit] !xternal lin"s


Gi iboo s has a boo on the topic of C Programming/Preprocessor &SO)&EC ?=??. The official CD6??? standard, along with defect reports and a rationale. %s of 7AA9 the latest "ersion is &SO)&EC ?=??DTC7. 2CB CPP online manual >isual Studio .CET preprocessor reference Collection of pre$defined macros

#igraphs and trigraphs


/rom Gi ipedia, the free encyclopedia 'Redirected from C trigraph* Pump toD na"igation, search This article needs additional citations for verification.
Please help impro"e this article by adding reliable references. Bnsourced material may be

challenged and remo"ed. September !""#$

&n computer programming, digrap s and trigrap s are sequences of two and three characters respecti"ely which are interpreted as one character by the programming language. >arious reasons e#ist for using digraphs and trigraphsD eyboards may not ha"e eys to co"er the entire character set of the language, input of special characters may be difficult, te#t editors may reser"e some characters for special use and so on. Trigraphs might also be used for some E.CE&C code pages that lac characters such as { and &.

Contents
4hide5

6 Fistory 7 &mplementations 8 (anguage support o 8.6 Pascal o 8.7 >im o 8.8 2CB Screen o 8.1 P o 8.9 C 1 Cotes 9 References

[edit] #istor$
The basic character set of the C programming language is a superset of the %SC&& character set that includes nine characters which lie outside the &SO :1: in"ariant character set. This can pose a problem for writing source code when the eyboard being used does not support any of these nine characters. The %CS& C committee in"ented trigraphs as a way of entering source code using eyboards that support any "ersion of the &SO :1: character set.

[edit] Implementations
Trigraphs are not commonly encountered outside compiler test suites.465 Some compilers support an option to turn recognition of trigraphs off, or disable trigraphs by default and require an option to turn them on. Some can issue warnings when they encounter trigraphs in source files. .orland supplied a separate program, the trigraph preprocessor, to be used only when trigraph processing is desired 'the rationale was to ma#imise speed of compilation*.

[edit] Language support


Eifferent systems ha"e different sets of defined trigraphsD

[edit] Pascal
Pascal programming language supports digraphs (., .), (F and F) for J, L, { and & respecti"ely. Bnli e all other cases mentioned here, (F and F) were in wide use.

[edit] Vim
>im te#t editor supports digraphs for actual entry of te#t characters, following R/C 6819.

[edit] $"% Screen


2CB Screen has a digraph command, bound to Q% Q> by default.

[edit] &
The P programming language uses dot and colon characters to e#tend the meaning of the basic characters a"ailable. These howe"er are not digraphs, because the resulting sequences do not ha"e a single$character equi"alent.

[edit] C
C programming language supports digraphs in &SO C ?1 mode of compiling. The C preprocessor replaces all occurrences of the following nine trigraph sequences by their single$character equi"alents before any other processing. % programmer may want to place two question mar s together yet not ha"e the compiler treat them as introducing a trigraph. The C grammar does not permit two consecuti"e P to ens, so the only places in a C file where two question mar s in a row may be used are in multi$character constants, string literals, and comments. To safely place two consecuti"e question mar s within a string literal, the programmer can use string concatenation "...P""P..." or an escape sequence "...P#P...". !rigrap "quivalent
PP8 PP. PPZ PP( PP) PP" PP< PP> # # \ J L = { &

PPPPP

is not itself a trigraph sequence.

The PP. trigraph can be used to introduce an escaped newline for line splicing! this must be ta en into account for correct and efficient handling of trigraphs within the preprocessor. &t can also cause surprises, particularly within comments. /or e#ampleD
.. )ill the ne't line (e e'ecutedPPPPPPPPPPPPPPPP. aOO$

which is a single logical comment line 'used in CII and C??*, and
.PP. F : comment FPP. .

which is a correctly formed bloc comment. &n 6??1 a normati"e amendment to the C standard, included in C??, supplied digraphs as more readable alternati"es to fi"e of the trigraphs. They areD #igrap "quivalent
<M M> <K K> KM J L { & #

Bnli e trigraphs, digraphs are handled during to eni+ation, and it must always represent a full to en by itself. &f a digraph sequence occurs inside another to en, for e#ample a quoted string, or a character constant, it will not be replaced.

'eader file
/rom Gi ipedia, the free encyclopedia Pump toD na"igation, search Some programming languages 'most famously C, CII, and Ob0ecti"e$C* use eader files. These files allow programmers to separate certain elements of a program,s source code into reusable files. Feader files commonly contain forward declarations of classes, subroutines, "ariables, and other identifiers. Programmers who wish to declare standardi+ed identifiers in more than one source file can place such identifiers in a single header file, which other code can then include whene"er the header contents are required. This is to eep the interface in the header separate from the implementation. The C standard library and CII standard library traditionally declare their standard functions in header files.

Cewer compiled languages 'such as Pa"a, C-* do not use forward declarations! identifiers are recogni+ed automatically from source files and read directly from dynamic library symbols. This means header files are not needed.

Contents
4hide5

6 3oti"ation 7 %lternati"es 8 See also 1 E#ternal lin s

[edit] Moti%ation
&n most modern computer programming languages, programmers can brea up programs into smaller components 'such as classes and subroutines* and distribute those components among many translation units 'typically in the form of physical source files*, which the system can compile separately. Once a subroutine needs to be used somewhere other than in the translation unit where it is defined, a way to refer to it must e#ist. /or e#ample, a function defined in this way in one source fileD
int add(int a int () { return a O ($ &

may be declared 'with a function prototype* and then referred to in a second source file as followsD
int add(int int)$

int triple(int ') { return add(' &

add('

'))$

One drawbac of this method is that the prototype must be present in all files that use the function. %nother drawbac is that if the return type or arguments of the function are changed, these prototypes will ha"e to be updated. This process can be automated with the C preprocessor 'i.e., getting an% prototype results in getting the latest one*. /or e#ample, the following code declares the function in a separate file 'the parameter names are not used by the compiler, but they can be useful to programmers*D /ile Jadd.hJ
#ifndef :<<_H_?@:4< #define :<<_H_?@:4< int add(int a int ()$

#endif

This file uses include guards to a"oid multiple definitions of the function. The following code demonstrates how header files are usedD
#include "add.h" int triple(int ') { return add(' add(' '))$ &

Cow, e"ery time the code is compiled, the latest function prototypes in add.h will be included in the files using them, a"oiding potentially disastrous errors.

[edit] Alternati%es
Some newer languages 'such as Pa"a* dispense with header files and instead use a naming scheme that allows the compiler to locate the source files associated with interfaces and class implementations. These languages 'and perhaps others* preser"e type information for functions in the ob0ect code, allowing the lin er to "erify that functions are used correctly. CO.O( and RP2 &> ha"e a form of include files called cop%books. Programmers JincludeJ these into the source of the program in a similar way to header files, but they also allow replacing certain te#t in them with other te#t. The CO.O( eyword for inclusion is N6PA, and replacement is done with a 43P;:N*+? ... 5A ... clause. /ortran does not require header files per se. Fowe"er, /ortran ?A and later has two related featuresD include statements and modules. The former can be used to share a common file containing procedure interfaces, much li e a C header, although the specification of an interface is not required for all "arieties of /ortran procedures. This approach is not commonly used! instead procedures are generally grouped into modules which can then be referenced with a use statement within other regions of code. /or modules, header$type interface information is automatically generated by the compiler, and typically put into separate module 'usually R.mod* files in a compiler$dependent format, although some compilers ha"e placed this information directly into ob0ect files. Cote that the language specification itself does not mandate the creation of any e#tra files, e"en though module procedure interfaces are almost uni"ersally propagated in this manner.

[edit] See also


One Eefinition Rule %pplication Programming &nterface &nterface Eefinition (anguage -pragma once

&ext su'stitution macros


(anguages such as C and assembly language ha"e rudimentary macro systems, implemented as preprocessors to the compiler or assembler. C preprocessor macros wor by simple te#tual search$and$replace at the to en, rather than the character, le"el. % classic use of macros is in the computer typesetting system Te@ and its deri"ati"es, where most of the functionality is based on macros. 3acro3( is an e#perimental system that see s to reconcile static typing and macro systems. Cemerle has typed synta# macros, and one producti"e way to thin of these synta# macros is as a multi$stage computation. Other e#amplesD

m1 is a sophisticated, stand$alone, macro processor. TR%C PFP 3acro E#tension T%(, accompanying Template %ttribute (anguage S3@, for web pages 3()6 3acro (anguage One The 2eneral Purpose 3acroprocessor is a conte#tual pattern matching macro processor, which could be described as a combination of regular e#pressions, E.C/ and %GS S%3;: minimac, a concatenati"e macro processor. troff and nroff, for typesetting and formatting Bni# manpages.

The preprocessor is a te#t processor that manipulates the te#t of a source file as part of the first phase of translation. The preprocessor does not parse the source te#t, but it does brea it up into to ens for the purpose of locating macro calls. %lthough the compiler ordinarily in"o es the preprocessor in its first pass, the preprocessor can also be in"o ed separately to process te#t without compiling. The reference material on the preprocessor includes the following sectionsD

Preprocessor directi"es Preprocessor operators Predefined macros Pragmas

Microsoft $pecific Hou can obtain a listing of your source code after preprocessing by using the )E or )EP compiler option. .oth options in"o e the preprocessor and output the resulting te#t to the

standard output de"ice, which, in most cases, is the console. The difference between the two options is that )E includes %line directi"es and )EP strips these directi"es out. "&# Microsoft $pecific Special Terminology &n the preprocessor documentation, the term JargumentJ refers to the entity that is passed to a function. &n some cases, it is modified by JactualJ or Jformal,J which describes the argument e#pression specified in the function call and the argument declaration specified in the function definition, respecti"ely. The term J"ariableJ refers to a simple C$type data ob0ect. The term Job0ectJ refers to both CII ob0ects and "ariables! it is an inclusi"e term. See %lso 'eference Phases of Translation (t er 'esources C)CII Preprocessor Reference

Preprocessor #irectives
)isual $tudio *++, Other >ersions

>isual Studio 7A6A >isual Studio 7AA= >isual Studio .CET 7AA8

Preprocessor directi"es, such as %define and %ifdef, are typically used to ma e source programs easy to change and easy to compile in different e#ecution en"ironments. Eirecti"es in the source file tell the preprocessor to perform specific actions. /or e#ample, the preprocessor can replace to ens in the te#t, insert the contents of other files into the source file, or suppress compilation of part of the file by remo"ing sections of te#t. Preprocessor lines are recogni+ed and carried out before macro e#pansion.

Therefore, if a macro e#pands into something that loo s li e a preprocessor command, that command is not recogni+ed by the preprocessor. Preprocessor statements use the same character set as source file statements, with the e#ception that escape sequences are not supported. The character set used in preprocessor statements is the same as the e#ecution character set. The preprocessor also recogni+es negati"e character "alues. The preprocessor recogni+es the following directi"esD -define -elif -else -endif -error -if -ifdef -ifndef -import -include -line -pragma -undef -using

The number sign '%* must be the first nonwhite$space character on the line containing the directi"e! white$space characters can appear between the number sign and the first letter of the directi"e. Some directi"es include arguments or "alues. %ny te#t that follows a directi"e 'e#cept an argument or "alue that is part of the directi"e* must be preceded by the single$line comment delimiter '--* or enclosed in comment delimiters '-. .-*. (ines containing preprocessor directi"es can be continued by immediately preceding the end$ of$line mar er with a bac slash '/*. Preprocessor directi"es can appear anywhere in a source file, but they apply only to the remainder of the source file.

Preprocessor Operators
)isual $tudio *++, Other >ersions

>isual Studio 7A6A >isual Studio 7AA= >isual Studio .CET 7AA8

/our preprocessor$specific operators are used in the conte#t of the %define directi"e 'see the following list for a summary of each*. The stringi+ing, chari+ing, and to en$pasting

operators are discussed in the ne#t three sections. /or information on the defined operator, see The -if, -elif, -else, and -endif Eirecti"es. (perator Stringi+ing operator '-* 0ction Causes the corresponding actual argument to be enclosed in double quotation mar s

Chari+ing operator Causes the corresponding argument to be enclosed in single quotation '-T* mar s and to be treated as a character '3icrosoft Specific* To en$pasting operator '--* defined operator See %lso %llows to ens used as actual arguments to be concatenated to form other to ens Simplifies the writing of compound e#pressions in certain macro directi"es

Predefined Macros
)isual $tudio *++, Other >ersions

>isual Studio 7A6A >isual Studio 7AA= >isual Studio .CET 7AA8

Cames the predefined %CS& C and 3icrosoft CII implementation macros. The compiler recogni+es predefined %CS& C macros and the 3icrosoft CII implementation pro"ides se"eral more. These macros ta e no arguments and cannot be redefined. Some of the predefined macros listed below are defined with multiple "alues. See the following tables for more information. 0&$I1Compliant 2redefined Macros Macro #escription

__#0!"__

The compilation date of the current source file. The date is a string literal of the form &mm dd %%%%. The month name &mm is the same as for dates generated by the library function asctime declared in T&3E.F.

The name of the current source file. __3I4"__ e#pands to a string surrounded by double quotation mar s. To ensure that the full path to the file is displayed, use )/C '/ull Path of Source Code /ile in Eiagnostics*. Hou can create your own wide string "ersion of __3I4"__ as followsD __3I4"__ Copy
#include <stdio.h> #define )*<3+-(') ; ## ' #define )*<3+(') )*<3+-(') #define __)I*;3__ )*<3+(__I*;3__) !char_t Fp!sU 8 __)I*;3__$ int main() {&

__4I&"__

The line number in the current source file. The line number is a decimal integer constant. &t can be altered with a %line directi"e. &ndicates full conformance with the %CS& C standard. Eefined as the integer constant 6 only if the )Ua compiler option is gi"en and you are not compiling CII code! otherwise is undefined. The most recent compilation time of the current source file. The time is a string literal of the form hh'mm'ss.

__$!#C__

__!IM"__

The date and time of the last modification of the current source file, e#pressed as a string literal in the form Ddd &mm Date hh'mm'ss __!IM"$!0M2__ %%%%, where Ddd is the abbre"iated day of the wee and Date is an integer from 6 to 86. Microsoft1$pecific 2redefined Macros Macro #escription _0!4_)"' _C50'_6&$I7&"# __C4'_)"' Eefines the %T( "ersion. Eefault c ar type is unsigned. Eefined when )P is specified. Eefines the "ersion of the common language runtime used when the application was compiled. The "alue returned will be in the following formatD 3mmbbbbb where,

3 is the ma0or "ersion of the runtime. mm is the minor "ersion of the runtime. bbbbb is the build number. Copy
.. clr_ver.cpp .. compile !ithM .clr using namespace 7/stem$ int main() { NonsoleMM)rite;ine(__N;4_234)$ &

Eefined when compiling with -clr, -clr8pure, or -clr8safe. >alue of NNcplusplusNcli is 7AA1A:. NNcplusplusNcli is in effect throughout the translation unit. Copy __cplusplus_cli
.. cplusplus_cli.cpp .. compile !ithM .clr #include "stdio.h" int main() { #ifdef __cplusplus_cli printf("Kd#n" __cplusplus_cli)$ #else printf("not defined#n")$ #endif &

E#pands to an integer starting with A and incrementing by 6 e"ery time it is used in a compiland. __C(6&!"'__ remembers its state when using precompiled headers. &f the last __C(6&!"'__ "alue was 1 after building a precompiled header 'PCF*, it will start with 9 on each PCF use. __C(6&!"'__ lets you generate unique "ariable names. Hou can use to en pasting with a prefi# to ma e a unique name. /or e#ampleD Copy
.. pre_mac_counter.cpp #include <stdio.h> #define I@+N-(' /) '##/ #define I@+NB(' /) I@+N-(' /) #define I@+N(') I@+NB(' __N6@+934__) int I@+N(m/_uniYue_prefi')$

__C(6&!"'__

int I@+N(m/_uniYue_prefi')$ int main() { m/_uniYue_prefi'% 8 %$ printf_s("#nKd" m/_uniYue_prefi'%)$ m/_uniYue_prefi'%OO$ printf_s("#nKd" m/_uniYue_prefi'%)$ &

__cplusplus _C224IB_)"'

Eefined for CII programs only. Eefined if you include any of the CII Standard (ibrary headers! reports which "ersion of the Ein umware header files are present. Eefined for code compiled with )2R 'Enable Run$ Time Type &nformation*. Eefined for code compiled with )2@ 'Enable E#ception Fandling*. Eefined when compiling with )(Ed, )3Ed, and )3Td. Eefined when )3E or )3Ed '3ultithread E((* is specified. >alid only within a function and returns the decorated name of the enclosing function 'as a string*. __36&C#&0M"__ is not e#panded if you use the )EP or )P compiler option. >alid only within a function and returns the signature of the enclosing function 'as a string*. __36&C$I7__ is not e#panded if you use the )EP or )P compiler option. On a :1$bit operating system, the calling con"ention is __cdecl by default. >alid only within a function and returns the undecorated name of the enclosing function 'as a string*. __36&C!I(&__ is not e#panded if you use the )EP or )P compiler option. Reports the ma#imum si+e 'in bits* for an integral type. Copy

_C22'!!I _C226&9I&# _#"B67 _#44

__36&C#&0M"__

__36&C$I7__

__36&C!I(&__

_I&!"7'04_M0:_BI!$

.. integral_ma'_(its.cpp #include <stdio.h> int main() { printf("Kd#n" _*+93?4:;_>:T_5*97)$ &

_M_04250 _M_C"" _M_C""_26'" _M_C""_$03" _M_I:<= _M_I0=>

Eefined for EEC %(PF% platforms 'no longer supported*. Eefined for a compilation that uses any form of -clr '-clr8old$ynta;, -clr8safe, for e#ample*. Eefined for a compilation that uses -clr8pure. Eefined for a compilation that uses -clr8safe. Eefined for #=: processors. See >alues for N3N&@=: for more details. Eefined for &tanium Processor /amily :1$bit processors. E#pands to a "alue indicating which -arc compiler option was usedD

A if -arc was not used. 6 if -arc 8$$" was used. 7 if -arc 8$$"* was used. See )arch '3inimum CPB %rchitecture* for more information.

_M_I:<=_32

_M_M22C _M_M':+++ _M_22C _M_:=> _M0&07"# _M3C_)"'

Eefined for Power 3acintosh platforms 'no longer supported*. Eefined for 3&PS platforms 'no longer supported*. Eefined for PowerPC platforms 'no longer supported*. Eefined for #:1 processors. Eefined to be 6 when )clr is specified. Eefines the 3/C "ersion. /or e#ample, A#A;AA represents 3/C "ersion ;.

_M$C_":!"&$I(&$

_M$C_)"'

This macro is defined when compiling with the )Ue compiler option 'the default*. &ts "alue, when defined, is 6. Reports the ma0or and minor "ersions of the compiler. /or e#ample, 686A for 3icrosoft >isual CII .CET 7AA8. 686A represents "ersion 68 and a 6.A point release. The >isual CII 7AA9 compiler "ersion is 61AA. Type cl -? at the command line to see the ma0or and minor "ersions of your compiler along with the build number.

__M$)C_'6&!IM"_C5"C@$ _M!

Eefined when one of the )RTC compiler options is specified. Eefined when )3E or )3Ed '3ultithreaded E((* or )3T or )3Td '3ultithreaded* is specified.

_&0!I)"_9C50'_!_#"3I&"# Eefined when )UcDwcharNt is used. Eefined when compiling with )openmp, returns an integer representing the date of the Open3P specification implemented by >isual CII. Copy _(2"&M2
.. _6P3+>P_dir.cpp .. compile !ithM .openmp #include <stdio.h> int main() { printf("Kd#n" _6P3+>P)$ &

_)C_&(#"3064!4IB

Eefined when -Al is used! see )Ul 'Omit Eefault (ibrary Came* for more information. Eefined when )UcDwcharNt is used or if wcharNt is defined in a system header file included in your pro0ect. Eefined for applications for Gin87 and Gin:1. %lways defined. Eefined for applications for Gin:1. Eefined when specifying )Gp:1.

_9C50'_!_#"3I&"#

_9I&B* _9I&=> _9p=>

%s shown in following table, the compiler generates a "alue for the preprocessor identifiers that reflect the processor option specified. )alues for _M_I:<= (ption in #evelopment Command14ine "nvironment (ption .lend Pentium )2. )29

'esulting )alue _M_I:<= C =++ 'Eefault. /uture compilers will emit a different "alue to reflect the dominant processor.* _M_I:<= C ,++ _M_I:<= C =++ _M_I:<= C B++ _M_I:<= C >++

Pentium Pro, Pentium &&, )2: and Pentium &&& =A8=: =A1=: See %lso 'eference )28 )21

Pragma #irectives
)isual $tudio *++, Other >ersions

>isual Studio 7A6A >isual Studio 7AA= >isual Studio .CET 7AA8

Copy
#pragma toDen-string

Remar s Each implementation of C and CII supports some features unique to its host machine or operating system. Some programs, for instance, need to e#ercise precise control o"er the memory areas where data is placed or to control the way certain functions recei"e parameters. The %pragma directi"es offer a way for each compiler to offer machine$ and operating system$specific features while retaining o"erall compatibility with the C and

CII languages. Pragmas are machine$ or operating system$specific by definition, and are usually different for e"ery compiler. Pragmas can be used in conditional statements, to pro"ide new preprocessor functionality, or to pro"ide implementation$defined information to the compiler. The 3icrosoft C and CII compilers recogni+e the following pragmasD allocNte#t chec Nstac component dataNseg floatNcontrol hdrstop inlineNdepth ma eNpublic omp pac pushNmacro section unmanaged autoNinline codeNseg conform6 deprecated fpNcontract includeNalias inlineNrecursion managed once pointersNtoNmembers6 region, endregion setlocale "tordisp6 bssNseg comment constNseg fen"Naccess function initNseg6 intrinsic message optimi+e popNmacro runtimeNchec s strictNgsNchec warning

6. Supported only by the CII compiler. The token-string is a series of characters that gi"es a specific compiler instruction and arguments, if any. The number sign '%* must be the first non$white$space character on the line containing the pragma! white$space characters can separate the number sign and the word pragma. /ollowing %pragma, write any te#t that the translator can parse as preprocessing to ens. The argument to %pragma is sub0ect to macro e#pansion. &f the compiler finds a pragma it does not recogni+e, it issues a warning, but compilation continues.

Some pragmas pro"ide the same functionality as compiler options. Ghen a pragma is encountered in source code, it o"errides the beha"ior specified by the compiler option. /or e#ample, if you specified )Up=, you can o"erride this compiler setting for specific portions of the code with pac D Copy
cl .WpH ... <file> - pacDing is H .. ... #pragma pacD(push B) - pacDing is no! B .. ... #pragma pacD(pop) - pacDing is H <.file>

See %lso

Macros (C)C**+
)isual $tudio *++, Other >ersions

>isual Studio 7A6A >isual Studio 7AA= >isual Studio .CET 7AA8

Preprocessing e#pands macros in all lines that are not preprocessor directi"es 'lines that do not ha"e a % as the first non$white$space character* and in parts of some directi"es that are not s ipped as part of a conditional compilation. JConditional compilationJ directi"es allow you to suppress compilation of parts of a source file by testing a constant e#pression or identifier to determine which te#t bloc s are passed on to the compiler and which te#t bloc s are remo"ed from the source file during preprocessing. The %define directi"e is typically used to associate meaningful identifiers with constants, eywords, and commonly used statements or e#pressions. &dentifiers that represent constants are sometimes called Jsymbolic constantsJ or Jmanifest constants.J &dentifiers that represent statements or e#pressions are called Jmacros.J &n this preprocessor documentation, only the term JmacroJ is used. Ghen the name of the macro is recogni+ed in the program source te#t or in the arguments of certain other preprocessor commands, it is treated as a call to that macro. The macro name is replaced by a copy of the macro body. &f the macro accepts arguments, the actual arguments following the macro name are substituted for formal parameters in the macro

body. The process of replacing a macro call with the processed copy of the body is called Je#pansionJ of the macro call. &n practical terms, there are two types of macros. JOb0ect$li eJ macros ta e no arguments, whereas Jfunction$li eJ macros can be defined to accept arguments so that they loo and act li e function calls. .ecause macros do not generate actual function calls, you can sometimes ma e programs run faster by replacing function calls with macros. '&n CII, inline functions are often a preferred method.* Fowe"er, macros can create problems if you do not define and use them with care. Hou may ha"e to use parentheses in macro definitions with arguments to preser"e the proper precedence in an e#pression. %lso, macros may not correctly handle e#pressions with side effects. See the getrandom e#ample in The -define Eirecti"e for more information. Once you ha"e defined a macro, you cannot redefine it to a different "alue without first remo"ing the original definition. Fowe"er, you can redefine the macro with e#actly the same definition. Thus, the same definition can appear more than once in a program. The -undef directi"e remo"es the definition of a macro. Once you ha"e remo"ed the definition, you can redefine the macro to a different "alue. The -define Eirecti"e and The -undef Eirecti"e discuss the %define and %undef directi"es, respecti"ely. /or more information, see,

3acros and CII >ariadic 3acros Predefined 3acros

See %lso (t er 'esources C)CII Preprocessor Reference

Potrebbero piacerti anche