preprocessor symbol table doubt 
Author Message
 preprocessor symbol table doubt

hi,

recently my friends was asked to interview few candidates,
and was handed an existing C language test for screening.
she encountered a question (which has an answer for the
interviewer to refer to), with which she was not convinced
herself (of course she skipped the question and asked a
different one).

i tried it out myself, and am a bit baffled by the outcome
of trying out the code snippet myself.

consider this...

#define A B
#define B C
#define C B

main()
{
  int  A, B, C;
  ...

Quote:
}

to me it looks like in the preprocessing stage the symbols
would resolve to

A->B->C->B = A->B
B->C->B = B->B
C->B = C->B

therefore the declaration/definition inside main resolves
to
  int B, B, B;

but when i tried compiling with "gcc" (version 2.93 i think),
with "-E" option (i.e. preprocess only), what i got was :

  int B, B, C;

of course the answer suggested in the original question paper
given to my friend was...

  int A, A, B;

this is what is baffling me. it this a compiler dependent
feature. i don't think at this state the optimization has
still taken place to remove "sub-expression"... etc. so,
can someone explain the behaviour of "gcc" ??

thanks,
banibrata dutta.
--



Wed, 22 Sep 2004 05:57:02 GMT  
 preprocessor symbol table doubt
On 05 Apr 2002 21:57:02 GMT, Banibrata Dutta said:

Quote:
> consider this...

> #define A B
> #define B C
> #define C B

> main()
> {
>   int  A, B, C;
>   ...
> }

> to me it looks like in the preprocessing stage the symbols
> would resolve to

> A->B->C->B = A->B
> B->C->B = B->B
> C->B = C->B

To me it looks like each preprocessing instruction will be
executed on the same token at most once, but that the same token
might get operated on a few times, not necessarily in top-down
fashion. So I read this as
A->B->C->B
B->C->B
C->B->C

So I get B,B,C, which is what gcc gives.  But to show more
warpedness, and perhaps show more clearly what happens, here's a
replacement for your macros...

#define A B
#define B C _ C
#define C A _ A _ A

int main(void)
{
   int A, B, C;
   return 0;

Quote:
}

gives me

int main(void)
{
  int A _ A _ A  _ A _ A _ A  , B  _ B  _ B   _ B  _ B  _ B   ,
      C _ C   _ C _ C   _ C _ C   ;
  return 0;

Quote:
}

so what seems to me to be happenning is what I said. Whether this
is conformant I don't know.

Dave.

--
          David Neary,
  E-Mail: bolsh at gimp dot org
--



Thu, 23 Sep 2004 07:12:31 GMT  
 preprocessor symbol table doubt


Quote:
>hi,

>recently my friends was asked to interview few candidates,
>and was handed an existing C language test for screening.
>she encountered a question (which has an answer for the
>interviewer to refer to), with which she was not convinced
>herself (of course she skipped the question and asked a
>different one).

>i tried it out myself, and am a bit baffled by the outcome
>of trying out the code snippet myself.

>consider this...

>#define A B
>#define B C
>#define C B

>main()
>{
>  int  A, B, C;
>  ...
>}

>to me it looks like in the preprocessing stage the symbols
>would resolve to

>A->B->C->B = A->B
>B->C->B = B->B
>C->B = C->B

Here's my interpretation based on my understanding of this section of
C99 that talks about macro replacement:

6.10.3.4(2):

2 If the name of the macro being replaced is found during this scan of
the replacement list (not including the rest of the source files
preprocessing tokens), it is not replaced. Furthermore, if any nested
replacements encounter the name of the macro being replaced,
it is not replaced. These nonreplaced macro name preprocessing tokens
are no longer available for further replacement even if they are later
(re)examined in contexts in which that macro name preprocessing token
would otherwise have been replaced.

Symbol table after the defines:

symbol   replacement text
A           B
B           C
C           B

Expansion of A:

A->B->C->B

A->B (OK)
B->C (OK)
C->B (Stop replacement, B has been encountered).

Expansion of B:

B->C->B

B->C (OK)
C->B (Stop, Same as above)

Expansion of C:

C->B->C

C->B (OK)
B->C (Stop, C has been encountered)

After preprocessing:

main()
{
  int  B,B,C;
  ...

Quote:
}

Without this rule, I suppose that the preprocessor would get stuck in
an infinite state of recursion in the example above.

<snip>

Russ
--



Thu, 23 Sep 2004 07:12:37 GMT  
 preprocessor symbol table doubt

Quote:

>   int B, B, C;

is the correct outcome from applying the rules in the C standard.
The name of a (possibly recursive) macro being expanded is not
subject to further replacement.  This is sometimes known as the
"blue paint" rule.
--



Thu, 23 Sep 2004 07:12:48 GMT  
 preprocessor symbol table doubt

Quote:

> #define A B
> #define B C
> #define C B
> main()
> {
>   int  A, B, C;
>   ...
> }
> to me it looks like in the preprocessing stage the symbols
> would resolve to
> A->B->C->B = A->B
> B->C->B = B->B
> C->B = C->B

No. That last one becomes

  C->B->C   i.e. C->C

See below for the reason.

Quote:
> of course the answer suggested in the original question paper
> given to my friend was...
>   int A, A, B;

Completely wrong.  Which only goes to show that this whole question is
*very* badly chosen as a test of C programming skills.  Every
competent C programmer's honest answer to this would be: The question
is stupid --- nobody should ever do that, thus nobody needs to know
what would happen.

Quote:
> this is what is baffling me. it this a compiler dependent
> feature.

No. At least not as long as you only consider correct,
standards-conforming compilers.  The exact details of this are
defined by the ANSI C standard.

Quote:
>i don't think at this state the optimization has still taken place to
> remove "sub-expression"... etc. so, can someone explain the
> behaviour of "gcc" ??

Optimization has no say in this.  But the definition of the
preprocessing stage of a C translation system does.

The first key to this behaviour is that in the C preprocessor, no
expansion at all takes place at the time a macro is *defined*, but
only when it's *used*.  (Your explanation expects the opposite, I
think.)

Obviously, this could lead to infinite expansion, i.e.  B expands into
C, which expands into B, which expands into C again, and so on,
forever (or rather until either your RAM or your patience ends).  To
avoid this, there's a special rule about macro expansion: while a
given macro is being expanded, that macro is effectively turned off.
So any 'B' that pops up during the expansion of macro B remains
unexpanded.

--

Even if all the snow were burnt, ashes would remain.
--



Thu, 23 Sep 2004 07:13:01 GMT  
 preprocessor symbol table doubt


[...]

Quote:

>consider this...

>#define A B
>#define B C
>#define C B

>main()
>{
>  int  A, B, C;
>  ...
>}

The three macro invocations resolve to B, B and C respectively, as gcc
does. Frankly I think you were just mistaken about the last expansion,
since you seem to know the rule, which is BTW very simple (and AFAIK
is the same in C89, C90 and C++): during rescanning of a macro
replacement list, the name of the macro being replaced is never
replaced.

Quote:
>of course the answer suggested in the original question paper
>given to my friend was...

>  int A, A, B;

Why do you say "of course"? :)

Genny.
--



Thu, 23 Sep 2004 07:13:02 GMT  
 preprocessor symbol table doubt


Quote:
>the rule is AFAIK the same in C89, C90 and C++

Of course I meant C90, C99 and C++ (98). Sorry

Genny.
--



Fri, 24 Sep 2004 12:34:37 GMT  
 preprocessor symbol table doubt
is their something particularly recursive about blue paint? i am imagining
someone painting, for example, a house and cursing.
--



Fri, 24 Sep 2004 12:34:51 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. preprocessor symbol table doubt

2. #define - cannot define/undefine preprocessor symbols after first token in file

3. Preprocessor Q: conditional comparison when the symbol is undefined

4. preprocessor symbol

5. Incrementing of preprocessor symbols

6. Determining what canned preprocessor symbols are available

7. Question re:Preprocessor Symbols

8. binary tree & symbol table modifications

9. duplicate symbol table entries in libc.a

10. unable to show symbol table for YACC if the grammar is correct

11. extracting data from symbol table

12. Walking the symbol table

 

 
Powered by phpBB® Forum Software