nikola
nikola

Reputation: 125

Macro output explanation

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

Answers (3)

luk32
luk32

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

Geoffrey
Geoffrey

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

VoidPointer
VoidPointer

Reputation: 3107

You miss spaces

#define X (4+Y)
#define Y (X+3)

Upvotes: 1

Related Questions