Reputation: 45
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?
Upvotes: 0
Views: 78
Reputation: 4537
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).
Upvotes: 0
Reputation: 24100
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.
Upvotes: 3