Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro output explanation

Tags:

c

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?

like image 695
nikola Avatar asked Mar 09 '26 17:03

nikola


2 Answers

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.

like image 146
luk32 Avatar answered Mar 12 '26 07:03

luk32


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.

like image 33
Geoffrey Avatar answered Mar 12 '26 09:03

Geoffrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!