Reputation: 125
When I run the following code,
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("%d",4*X+2);
return 0;
}
I am getting the following output:
Error: Undefined symbol 'X'
Can someone please explain the output?
Upvotes: 2
Views: 1080
Reputation: 16090
It is because the macro expects and argument since its defined with parentheses. You would need to define it as
#define X 4+Y
and #define Y X+3
. Then you would run into another trouble because of cyclic definition in macros.
To be even more correct, as Drew suggested; when the example would be compilable when defining macros one usually puts the parentheses around expression to ensure expected operator precedence.
So your best shot would be:
#define X (4+Y)
#define Y (X+3)
Very close to your initial example, just a space character between name of a macro and its definition. However, it is still impossible to properly expand the macro due to the cyclic reference.
How to check what happened:
You can use gcc -E
, which outputs a pre-processed file. It generates lots of output so I used tail
. I also used 2>err
to redirect error stream to a file, so the output is clear.
luk32:~/projects/tests$ gcc -E ./cyclic_macro_with_no_spaces.c 2> err | tail -n 6
int main()
{
printf("%d",4*X+2);
return 0;
}
luk32:~/projects/tests$ gcc -E ./cyclic_macro.c 2> err | tail -n 6
int main()
{
printf("%d",4*(4+(X+3))+2);
return 0;
}
In 1st example the X
did not expand at all. While in the latter both macros got expanded, although only one. Giving the same output that Geoffrey presented in his answer.
Whether no space is a typo or not there is an undefined symbol 'X'
. For different reason that are possible to trace by analyzing err
files.
Upvotes: 6
Reputation: 11374
If the macros are left as invalid function-like macros, they are not getting expanded at all because you did not call it with parentheses. So X is never replaced with anything by the pre-processor, and is the reason for the Undefined symbol 'X'
in your sample code.
If you wanted this to be expanded you would have to call it with parentheses like this:
printf("%d",4*X()+2);
This though would just error out when pre-processed as 4+Y
and X+3
are not valid macro parameter names.
If your answer is corrected somewhat so that those defines are proper defines, and not function-like macros, ie:
#define X (4+Y)
#define Y (X+3)
You have a circular reference between the defines...
X -> Y -> X... etc.
Since it will only expand the macro once, it is getting expanded to
printf("%d",4*(4+(X+3))+2);
This explains why X is the undefined symbol in this use case.
Upvotes: 5