Macro output explanation - 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?

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.

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.

You miss spaces
#define X (4+Y)
#define Y (X+3)

Related

Why is the output different in these two scenarios

Please give me full description....
The first snippet of code has the 'function call' (macro invocation) before the increment operator, and second one has the function call after the increment operator.
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b)++;
printf("%d%d",a,b);
return 0;
}
output:
124
why is 124 returned here
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b++);
printf("%d%d",a,b);
return 0;
}
output:
125
and 125 here?
The thing to keep in mind is that macros provide simple substitution of preprocessor tokens. In particular, they may evaluate their arguments more than once, and if not guarded by parentheses, they may produce unintended reassociation.
In the first example, we have
a=square (b)++;
This expands to:
a=b*b++;
This is actually undefined behavior, since the b and b++ are unsequenced, and b++ modifies b. In your case, you are seeing 12 and 4 for a and b, so it would seem that the first value of b is picking up the incremented value, so you're getting 4*3, but you can't count on this behavior. The final value of b is 4 since it is incremented once.
In the second example, we have:
a=square (b++);
This expands to:
a=b++*b++;
This is again undefined behavior. In your case, it appears that you're getting 4*3 (or 3*4), but again, you can't count on this behavior. The final value of b is 5 since it is incremented twice, but this too is undefined behavior.
In addition to Tom's answer, which explains what is happening, here is an example of how you could define a macro for squaring a number safely:
#define SQR(x) ( \
{ \
__auto_type x_ = (x); \
\
x_ * x_; \
} \
)
It only has an appearance of x, and therefore it doesn't evaluate it twice. The copy x_ is used instead. Note that variables created in a macro may conflict with other variables created in the function that calls the macro. To avoid name collisions you use special names that shouldn't be used in normal code such as a trailing _.
With this macro, this:
a = SQR(b++);
will be equivalent to this:
a = SQR(b);
b++;
Warning: This works on some compilers as an extension (GCC for example), but it is not standard C.
Another option, if you want standard C, is to use an inline function. It is ok if you want it to work on just one type (there is _Generic in C11, but I never used it, so no idea).

Why is the macro calling another macro showing error?

I wrote the following program and surprising it shows a compilation error that
'X' undeclared in exapansion of macro.
The code in c is:
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("ds", "ds");
printf("%d\n", 4*X+2);
return 0;
}
I accept that this results in a kind of infinite macro replacement, but if that was an error, that should have been a run time error(truly speaking no error at all). Am I correct? If not, please correct me and explain me where I am getting it wrong?
EDIT: I am surprised that the following code however works perfectly:
#include<stdio.h>
#define X (4+Y)
#define Y 4
int main()
{
printf("ds", "ds");
printf("%d\n", 4*X+2);
return 0;
}
The C preprocessor does not expand a macro while that macro is being expanded (including indirectly through another macro). So in the expansion of Y inside the expansion of X, the preprocessor leaves X as is, and thus you get an undefined variable error.
Not only does this prevent infinite expansion loops, it also provides a useful feature. Suppose, for example, that you want to write a macro which "wraps" an existing function:
#define my_function(x, y) do { \
fputs("Calling my_function\n", stderr); \
my_function(x, y); \
while(0);
The fact that my_function is not expanded inside its own expansion makes it possible to wrap the function with a macro with the same name, thereby avoiding source modifications.
For any passing language lawyers, the standard specifies (§6.10.3.4/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 file’s 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.
Creating .I file of your code in main.c file using gcc -E -o main.I main.c then we get a file which contains as below
int main()
{
printf("ds", "ds");
printf("%d\n", 4*(4+(X+3))+2);
return 0;
}
Hence macros just replaces the value. So in the expansion of Y inside the expansion of X, the preprocessor leaves X as is.
Hence as X is undefined error occurs.

Macro as an argument to a macro in C

I want to know which macro gets replaced first in the following code
#define A 100
#define B 200
#define C(A,B) A+B
here when we use C, then evaluation will be from left to right or right to left. That is B gets the value first or A gets the value first
i gave this example just to make things look simple, may be i was wrong. the actual thing i want to ask is, if A and B also take arguments and have the scope of expansion, then which one would expand first
I'm not sure what you mean. There's never a point where you can "see" half a result of the preprocessor; the entire input file is preprocessed, then handed over to the compiler.
I think that the names for the macro arguments will never also be replaced as if they were stand-alone symbols.
I tried it, and this program:
#include <stdio.h>
#define A 100
#define B 200
#define C(A, B) A + B
int main(void) {
printf("A=%d\nB=%d\nC(1,2)=%d\n", A, B, C(1,2));
return 0;
}
prints
A=100
B=200
C(1,2)=3
So, C(1,2) expands to 1 + 2, the definitions of A and B don't matter.
Of course I must say that I find the above very bad practice, since it's quite confusing. Never use all-caps names for macro arguments, since macros and preprocessor symbols tend to use such names.

macro arguments

What will the program print when the inputs are 2,3?
#include <stdio.h>
#define min(a,b) ((a) > (b) ? (b) : (a))
#define inc(a) a++
#define mult(a,b) (a * b)
int main(void) {
int x = 1, y = 2;
scanf("%d %d",&x,&y);
printf("min(%d,inc(%d))",x,y);
printf("=%d\n",min(x,inc(y)));
printf("min(mult(%d,%d+2),11)",x,y);
printf("=%d\n",min(mult(x,y+2),11));
return 0;
}
edit: I get funny answer for negative numbers i.e -1,-2.
Why is inc(-2) change y to zero instead of -1?
Think of a macro as simply string replacement. Just replace the macro name and parentheses with the body of the macro definition, replacing the macro parameters with what is passed in. An example is easier:
#define hello(a) a+a
...
int y = hello(x);
Would be replaced with:
int y = x+x;
To answer your question, do this manually, and very, very carefully. For nested macros, start with the inside one. Did I mention do this carefully? Don't add or remove any sets of parentheses.
The output would be:
min(2,inc(3))=2
min(mult(2,4+2),11)=11
What do you mean with overwrite?
If you define a function like you did above and call for example this:
inc(x);
.. then the compiler turns it into x++. The variable a is just a name for the "paramter" and will also be replaced by the real variable.
What operating system are you running? you can easily run this yourself and see the results
if your on Windows I would suggest getting CodeBlocks or Visual Studios
if your on Linux or MAC , learn to compile from terminal using gcc or g++

Why does my C program output this?

I am trying to solve two Preprocessor related questions but in both programs I am getting results that I am not able to figure out how. Below is my program:
#include<stdio.h>
#define SQUARE(x) x*x
int main()
{
float s=10,u=30 ,t=2,a;
a=2*(s-u*t)/SQUARE(t);
printf("Result:%f\n",a);
return 0;
}
According to me, the output of this programme should be -25.000 but I am getting -100.000.
And in second program:
#define FUN(i,j) i##j
int main()
{
int val1 = 10;
int val12 = 20;
clrscr();
printf("%d\n",FUN(val1,2));
getch();
}
Output should be 102 but I am getting 20;
why is it so?
#define SQUARE(x) x*x
should be
#define SQUARE(x) ((x)*(x))
Indeed, without the parentheses, 2*(s-u*t)/SQUARE(t) is expanded as
2*(s-u*t)/t*t
which is interpreted as
(2*(s-u*t)/t)*t
As to your second problem, FUN(val1,2) will get expanded as val12 per the semantics of the ## operator. It is still not clear what your intent is: the printf line will be understood as
printf("%d\n", val12);
which will print 20.
the first one:
a=2*(s-u*t)/SQUARE(t);
after replacing the define we get:
a=2*(s-u*t)/t*t;
now, since we don't have () in the definition of SQUARE we get:
a=2*(10-30*2)/2*2; --> a=2*(-50)/2*2; --> a=-100/2*2; --> a=-50*2; --> a=-100
if you want to get -25 you should define SQUARE(x) as (x*x).
Edit : add explanation regarding the second example.
printf("%d\n"FUN(val1,2));
once again, we first should replace the define (reminder: ## "concatenates" the string of the define - I can't find the perfect words in order to explain it so just take a look at the example...):
printf("%d\n",val12); [note: the comma (,) is missing - so it won't compile.]
since the value of val12 is 20 that's what you'll get.
the point of those 2 examples is to remember that we should always deal with the defines first (since in "real life" the compiler (or pre-processor) does it before the run time)
I hope it helps..
For the first case,
a=2*(s-u*t)/SQUARE(t);
would translate to
a=2*(s-u*t)/t*t;
at compile time. This is a common mistake made with preprocessors.
i know i am late, but i am having the perfect answer.
in c # at define is used to call the text as it is in the function parameter,
example, #define hai(s1) printf("%s=%s",#s1,s1);
in main: i am calling as hai(tom); tom was initialized as "india" string.
the output for this is tom=india, the calling string tom is printed by help of #.
similarly ## is used to take the text from function argument and join them and return the value of the joined identifier.
the above program has two argument va1 and 2. passed to i and j. then va1 and 2 is joined. and form va12.
va12 is the identifier available with value 20. that's why 20 is returned.

Resources