C program output is confusing - c

#include<stdio.h>
#include<conio.h>
#define PROD(x) (x*x)
void main()
{
clrscr();
int p=3,k;
k=PROD(p+1); //here i think value 3+1=4 would be passed to macro
printf("\n%d",k);
getch();
}
In my opinion, the output should be 16, but I get 7.
Can anyone please tell me why?

Macros are expanded, they don't have values passed to them. Have look what your macro expands to in the statement that assigns to k.
k=(p+1*p+1);
Prefer functions to macros, if you have to use a macro the minimum you should do is to fully parenthesise the parameters. Note that even this has potential surprises if users use it with expressions that have side effects.
#define PROD(x) ((x)*(x))

The preprocessor expands PROD(p+1) as follows:
k = (p+1*p+1);
With p=3, this gives: 3+1*3+1 = 7.
You should have written your #define as follows:
#define PROD(x) ((x)*(x))

The problem here is that PROD is a macro and will not behave exactly like you intend it to. Hence, it will look like this:
k = p+1*p+1
Which of course means you have:
k = 3+1*3+1 = 7

#define PROD(x) (x*x)
PROD(3+1) is changed by the preprocessor to 3+1*3+1

macro are not function . These are replaced by name
It will be p+1*p+1

This is what compiler is going to see after preprocessors does its job: k= p+1*p+1. When p = 3, this is evaluated as k = 3+(1*3)+1. Hence 7.

This is exactly why you should use functions instead of macros. A function only evaluates each parameter once. Why not try
int prod(int x)
{ return x * x; }
and see the difference!

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).

How does macro function in c uses the pass by reference

I' m learning Macro in c,
I wrote a small function in macro to swap number, but passed the value as 'pass by value' since i didn't use address of operator (&) before the variable in the argument, But when i ran the program. The value got swaped. You can refer the code and mention me where i got wrong in understanding?
#include<stdio.h>
#include<conio.h>
#define swap(a,b) a = a+b;b = a-b; a = a-b;
int main()
{
int x = 5, y = 10;
swap(x,y);
printf("%d %d\n",x,y);
getch();
return 0;
}
Do the arguments acts as pass by reference, when using it in macro?
C doesn't have pass-by-reference. And that's not what's happening here anyway. When a macro is "called", the preprocessor replaces the call-site with the body.
With your example, the invocation
swap(x,y);
is replaced by
x = x+y;y = x-y; x = x-y;;
This last line is what the actual parser of the compiler sees.
Many compilers have options to stop after the preprocessing step. I suggest you use that to see exactly what the preprocessor have done.
I also hope you start to see how macros can "break" your code.
For example if the code was
if (some_condition)
swap(x,y);
Then it would be expanded to (with some reformatting)
if (some_condition)
x = x+y;
y = x-y;
x = x-y;
;
This is clearly not what was intended and will not work.
You also have the case when the arguments to the macro are not simple variables, but expressions. Like
swap(x+1,y*2)
While would be replaced by
x+1 = x+1+y*2;y*2 = x+1-y*2; x+1 = x+1-y*2;;
This also would not work.

C prog error: expected expression before int

This is the program:
#include <stdio.h>
#define round(a) ((a-0.5)<int(a))?int(a):int(a+1)
int main() {
double a = 5.2;
int m = round(a);
printf("%d", m); }
and it shows the error: expected expression before 'int'
round is a name reserved by the standard C library so it is undefined behaviour to call your macro that name (even if you don't include math.h).
Your algorithm could be better expressed like this:
#define my_round(a) ( (int)((a) + 0.5) )
which also has the benefit of only evaluating its argument once.
It would be preferable to use an inline function:
inline int my_round(double d)
{
return d + 0.5;
}
Note that both options cause undefined behaviour if a is outside the bounds of INT_MIN, INT_MAX roughly . If it's in a critical environment you should make your inline function check the bounds of d before doing the conversion to int.
This
#define round(a) ((a-0.5)<int(a))?int(a):int(a+1)
Has the brackets in the wron places
Should be
#define round(a) (((int)((a)-0.5))<(a))?(int)(a):(int)(a+1)
The problem is that int(a) is not valid C.
Redefine your macro as follows:
#define round(a) (((a)-0.5)<(int)(a))?(int)(a):(int)(a+1)
Note that I've also added parentheses around a in (a)-0.5.
P.S. What's the reason for making it a macro and not, say, a function?
The error is because of int(a). Syntactically it is wrong. It should be (int)(a).

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++

C #define macros

Here is what i have and I wonder how this works and what it actually does.
#define NUM 5
#define FTIMES(x)(x*5)
int main(void) {
int j = 1;
printf("%d %d\n", FTIMES(j+5), FTIMES((j+5)));
}
It produces two integers: 26 and 30.
How does it do that?
The reason this happens is because your macro expands the print to:
printf("%d %d\n", j+5*5, (j+5)*5);
Meaning:
1+5*5 and (1+5)*5
Since it hasn't been mentioned yet, the way to fix this problem is to do the following:
#define FTIMES(x) ((x)*5)
The parentheses around x in the macro expansion prevent the operator associativity problem.
define is just a string substitution.
The answer to your question after that is order of operations:
FTIMES(j+5) = 1+5*5 = 26
FTIMES((j+5)) = (1+5)*5 = 30
The compiler pre-process simply does a substitution of FTIMES wherever it sees it, and then compiles the code. So in reality, the code that the compiler sees is this:
#define NUM 5
#define FTIMES(x)(x*5)
int main(void)
{
int j = 1;
printf("%d %d\n", j+5*5,(j+5)*5);
}
Then, taking operator preference into account, you can see why you get 26 and 30.
And if you want to fix it:
#define FTIMES(x) ((x) * 5)
the preprocessor substitutes all NUM ocurrences in the code with 5, and all the FTIMES(x) with x * 5. The compiler then compiles the code.
Its just text substitution.
Order of operations.
FTIMES(j+5) where j=1 evaluates to:
1+5*5
Which is:
25+1
=26
By making FTIMES((j+5)) you've changed it to:
(1+5)*5
6*5
30

Resources