Re: macro expansion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>> I have been playing around with gcc Pre-Processor and I cannot explain one
>> behavior.
>> The code bellow demonstrate my question.
>>
>> Input file :
>> ---------------------------------------
>> #define START_WITH_A_NUMBER      0_start_with_a_number
>> #define START_WITH_A_LETTER        a_start_with_a_letter
>> #define I_LOVE_SPACE                      I      love      space
>> START_WITH_A_NUMBER+0
>> START_WITH_A_LETTER+0
>> I_LOVE_SPACE
>> ---------------------------------------
>>
>> Pre-processed output (gcc -E -P myfile):
>> ---------------------------------------
>> 0_start_with_a_number +0
>> a_start_with_a_letter+0
>> I love space
>> ---------------------------------------
>>
>> 1) Why is there a space after '0_start_with_a_number' whereas no space is
>> present after 'a_start_with_a_letter'?
>>
>> 2) Why does gcc remove the spaces inside the replacement list of 
>> I_LOVE_SPACE?
>> 3) Does it serve a purpose?
>> 4) Is there a PP flag to force gcc to pre-process by the standard?
>
> To answer your last question first, the C99 standard describes a
> sequence of steps to compile a C program.  gcc is fully standard
> compliant in that regard.  The standard does not define the output of
> the preprocessor in a textual form.  So there is no standard to which
> gcc should conform.
>
>> 1) Why is there a space after '0_start_with_a_number' whereas no space is
>> present after 'a_start_with_a_letter'?
>
> There is a space after 0_start_with_a_number because gcc emits a space
> whenever necessary to prevent tokens from accidentally pasting together.
> E.g., a space is required between '+' and '=' in preprocessor output.
> The test for whether a space is necessary is conservative.
> 0_start_with_a_number is not an identifier, so the conservative test
> says that a space is required.

Could you give an example where tokens would accidentally be pasted together?
I cannot find any case where it would happen.

The reason behind my question, is that ISO/IEC 9899:TC3 contains an PP example 
which gcc outputs differently that the document.
On the second line, gcc puts a space between the '2' and the '+'.
gcc output: f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
doc output: f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
I know that it will not affect the compilation but I wanted to know the reason 
behind - thanks for your explanation.

--------------------------
EXAMPLE 3   To illustrate the rules for redefinition and reexamination, the 
sequence
#define x 3
#define f(a)      f(x * (a))
#undef   x
#define x 2
#define g f
#define z z[0]
#define h g(~
#define m(a)      a(w)
#define w 0,1
#define t(a)      a
#define p()        int
#define q(x)      x
#define r(x,y) x ## y
#define str(x) # x
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
-----------------------------
results in
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5,    };
char c[2][6] = { "hello", "" };
-----------------------------

>> 2) Why does gcc remove the spaces inside the replacement list of 
>> I_LOVE_SPACE?
>
> The spaces in the replacement list of I_LOVE_SPACE are removed because
> only one space is required to avoid accidental token pasting.  The
> additional spaces serve no purpose and are discarded.
Thanks, I also found the rule that gcc used. 
Copy/pasted for the record:
"The  source  file  is  decomposed  into  preprocessing  tokens  and  sequences  
of
white-space  characters  (including  comments).  A source  file  shall  not  
end  in  a
partial preprocessing token or in a partial comment.  Each comment is replaced 
by
one space character.  New-line characters are retained.  Whether each nonempty
sequence of white-space characters other than new-line is retained or replaced 
by
one space character is implementation-defined."

>> 3) Does it serve a purpose?
>
> I don't understand this question.
>
>
> In general the C/C++ preprocessor is not a general purpose text
> processing tool.  It is specifically designed as one of the passes in a
> C/C++ compiler.  Attempts to use it as a text processing tool are
> generally misguided.
The question is for education purpose. I have noooo plan to use gcc as a text 
processor :)

Matti


      



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux