ID Number: Q50341
5.00 5.10 6.00 6.00a 6.00ax | 5.10 6.00 6.00a
MS-DOS | OS/2
Summary:
The preprocessor of the Microsoft C Optimizing Compiler versions 5.0,
5.1, 6.0, 6.0a, and 6.0ax does not preserve the source code structure
of macro invocations upon expansion. Preprocessor macro expansion is
carried out on one line at a time, in a left to right fashion, until
the end-of-line is reached. Thus, when multiple-line macro invocations
are expanded, they are converted into a single line of code.
The following example defines a simple macro and displays this
conversion of multiline macro invocations:
#define macro( arg1, arg2, arg3 ) arg1 + arg2 + arg3
Source Code Preprocessor Listing
----------- --------------------
value = macro ( param1, value = macro( param1 + param2 + param3 );
param2,
param3 );
Note that the preprocessor listing replaces the three lines of code
in the source file with only one line. As a result, the line numbers
between the two files are different because the preprocessor does not
perform any line number adjustment.
This may cause problems if you must compile preprocessor listings to
avoid errors generated by .C source files (for example, insufficient
heap space). When the preprocessor listing is compiled, the subtle
side effect becomes more obvious in the form of discrepancies between
original source-code line numbers and line numbers associated with
compiler errors or debugger maps. This result can make debugging
original source code difficult, and can be a general nuisance when
trying to locate erroneous lines in source code indicated by the
compiler.
The #line directive and the __LINE__ predefined macro can be used to
redefine preprocessor listing line numbers and eliminate such
differences. To compensate for the preprocessor single-line expansion
of macro invocations, place the directive "#line __LINE__" in the
source code line following the macro invocation.
The #line directive, which accepts an integer constant as an argument,
instructs the preprocessor to change the compiler's internally stored
line number to the integer argument specified. The __LINE__ macro,
which is supplied as the argument to the #line directive, evaluates to
the current line number generated during preprocessing. Working
together, they force the compiler to generate consistent line numbers
between the the source file and the preprocessor listing.
The program below illustrates the macro expansion behavior of the C
preprocessor and how it can be modified to generate
line-number-compatible source and preprocessor listings.
More Information:
/* TEST.C */ | /* TEST.I */
|
/*1*/ #define sum( a,b,c) a+b+c | /*1*/ #define sum(a,b,c) a+b+c
/*2*/ | /*2*/
/*3*/ void main( void ) | /*3*/ void main( void )
/*4*/ { | /*4*/ {
/*5*/ int i; | /*5*/ int i;
/*6*/ i = sum( 1, | /*6*/ i = sum( 1, 2, 3 );
/*7*/ 2, | /*7*/ /* #line __LINE__ */
/*8*/ 3 ); | /*8*/ i = 100000;
/*9*/ /* #line __LINE__ */ | /*9*/ }
/*10*/ i = 100000; | /*10*/
/*11*/ } | /*11*/
|
When the program TEST.C above is compiled under warning level 3, a
data conversion warning is generated for line 10, indicating overflow
of the integer variable i. TEST.C is then run through the preprocessor
using the /P compiler option, where TEST.I (above) is generated.
Compiling TEST.I under warning level 3 generates the same data
conversion warning, but on line 8. The line number difference between
TEST.C and TEST.I is obvious.
By uncommenting line 9 in TEST.C, both the source file and
preprocessor listing contain consistent line numbers following the
macro invocation, because the line number is reset to the proper value
(7) after the preprocessor pass.
Additional reference words: 5.00 5.10 6.00 6.00a 6.00ax