this program prints out -8 -4 but i wanna know why and why isn't the compiler showing an error about which function to use? why are the results different. i don't know much about defining a function like this can someone explain this too
#include <stdio.h>
#include <stdlib.h>
int foo(int x, int y);
#define foo(x, y) x/y + x
int main() {
int i = -6, j = 3;
printf("%d ", foo(i + j, 3));
#undef foo
printf("%d\n", foo(i + j, 3));
}
int foo(int x, int y) {
return x/y + x;
}
If you preprocess the call to the macro foo
, you get:
i + j / 3 + i + j
With your values, that's
(-6) + 3 / 3 + (-6) + 3
Which evaluates to -8
.
When you undefine the macro foo
, you get the function foo
instead, where the line return x + y / x
is executed.
With i = -6
and j = 3
, you get:
(-3) / 3 + -3
Which is -4
.
Further reading:
These two functions are not equivalent due to operator precedence rules.
Remember a #define
macro does inline substitution and the arguments themselves are replaced as-is:
#include <stdio.h>
#include <stdlib.h>
int oper_fn(int x, int y) {
return x/y + x;
}
#define oper_def(x, y) x / y + x
int main() {
int i = -6, j = 3;
printf ("oper_fn=%d ",oper_fn( i + j , 3));
printf ("oper_def=%d\n",oper_def( i + j , 3));
}
What this ends up doing is evaluating:
i + j / 3 + i + j
Due to order of operations, this evaluates as:
i + (j / 3) + i + j
That's not what you want, instead you want:
(i + j) / 3 + (i + j)
Which means you need the macro:
#define oper_def(x, y) ((x) / (y) + (x))
That's how macros are written normally to avoid ambiguity and inconsistency like this.
Your #define
is not at all like the function. It evaluates as
printf ("%d ",i + j / 3 + i + j);
which will naturally generate a different result to the function as the parameters passed the function are evaluated so it sees x
as -3 and y
as 3.
when you define
#define foo(x, y) x / y + x
and then do
foo( i + j , 3));
you get
i + j / 3 + i + j
which is
-6 + 3/ 3 + 3 -6 = -6 + 1 + 3 - 6 = -8
when you call the function foo the i+j is evaluated first
if you want the correct define behavior then do
#define foo(x, y) ((x / y) + x)
You have just discovered why define
d functions are a bad idea
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.