Link to home
Start Free TrialLog in
Avatar of riceman0
riceman0

asked on

How is a circular #define resolved?

Can someone explain why the code below returns the error:

'SAM1': undeclared identifier

On the 'x=' line?

I would think that the first #define would be fine, then the second #define would be expanded to

#define SAM2 SAM2

which essentially has no effect, so I would expect the error to be

'SAM2': undeclared identifier

after the " int x = SAM1;" is expanded to  " int x = SAM2;

but apparently I misunderstand.  What does happen in this case?

Thanks.
#define SAM1 SAM2
#define SAM2 SAM1
 
int main()
{
       int x = SAM1;
	return 0;
}

Open in new window

Avatar of mrjoltcola
mrjoltcola
Flag of United States of America image

The ISO preprocessor is not recursive. It simple expands the text once. If there are recursive macros, they are not expanded by the preprocessor, but instead the program is passed to the compiler. If you try GCC with the traditional-cpp flag you get different results than default.


msmith@dmz ~]$ gcc -traditional-cpp t.c
t.c:10: error: detected recursion whilst expanding macro "SAM1"
t.c:10: error: detected recursion whilst expanding macro "SAM2"

http://gcc.gnu.org/onlinedocs/cpp/Traditional-macros.html

So what happens in ISO mode is the preprocessor makes one pass and translates to:

int main()
{
       int x = SAM2;
	return 0;
}

Open in new window

Avatar of ozo
what version of cc are you using, with what switches?
what do you get with
cc -E
Avatar of riceman0
riceman0

ASKER

Not sure I understand the answer, my "model" involves one pass, but assumes that earlier #defines can affect subsequent #defines, and would work like this:

#define SAM1 SAM2  ... store macro "SAM1->SAM2"
#define SAM2 SAM1  ... expand to "#define SAM2 SAM2" and store macro  "SAM2->SAM2"
int x = SAM2;  .. expand to "int x = SAM2;" and register error 'undefined identifier SAM2'

instead I got the error 'undefined identifier SAM1', as if the first #define didn't affect the second.

my "model" works with the code below, as follows

#define SAM2 SAM3  ... store macro "SAM1->SAM2"
#define SAM1 SAM2  ... expand to "#define SAM1 SAM3" and store macro  "SAM1->SAM3"
int x = SAM1;  .. expand to "int x = SAM3;" and register error 'undefined identifier SAM3'

which is the error I got.  So it looks like the first #define affected the second #define.

So obviously my "model" is wrong, can you tell me what's wrong with it?

Thanks.



#define SAM2 SAM3
#define SAM1 SAM2
 
 
int main()
{
int x = SAM1;   //error C2065: 'SAM3' : undeclared identifier
 
	return 0;
}

Open in new window

I told you wrong. By one pass, I meant it will not recursively evaluate (at least the ISO standard says so) macros, in the sense of self-referential.

However, I am looking for a good explanation, obviously I cannot explain it well enough myself as I do not fully understand the semantics.
ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial