Reputation: 303
I have the simple following C code
#define Sqrt(A) A * A
int main(void) {
int A = 10;
int x = Sqrt(A+1);
return 0;
}
For some reason, when I used it like that, with A+1, I get x to be 21, which is probably 10+11. My question is, how is the multiplication is being ignored? If I switch the macro with the macro text, I get the right result which is 121.
Thanks.
Upvotes: 0
Views: 198
Reputation: 651
when you call x = MACRO_NAME(A+1); this statement is replace as x = A + 1 * A + 1
in c priority of multiplication is more than addition so it will be 1st executed 1*A which give as A, then A+A+1 will give you result as 21`enter code here`
i.e A+1*A+1
= A+A+1
= 21
for proper answer you need to write Macro as #define MACRO_NAME(A) (A) * (A) which give you result as
121
Upvotes: 0
Reputation: 17572
Macros are substituted literally and then evaluated.
Since multiplication has more priority than addition, when you give A+1
to the macro it becomes 10 + 1 * 10 + 1
=> 10 + 10 + 1
=> 21
Likewise if you give A+2
..... 10 + 2 * 10 + 2
=> 10 + 20 + 2
=> 32
.
Upvotes: 0
Reputation: 1
First, your Sqrt
is misnamed, should be Square
(not square root)
Then, generate the preprocessed form (i.e. with gcc -C -E
) and look inside it.
#define Sqr(A) A * A
int a = 10;
int x = Sqr(a+1);
where the last line is expanded as
int x = a+1 * a+1;
Which is parsed as
int x = a+(1*a)+1;
Moral of the story, always use extra parenthesis in macro definition, i.e.
#define Sqr(A) ((A)*(A))
Even with such a definition, Sqr(a++)
is probably undefined behavior and at least is naughty.
So you want to avoid macros and actually, learn to use inline functions like
inline int square(int a) { return a*a; };
BTW, you will want to make it static inline
not just inline
(and put that in a header file)
Upvotes: 5
Reputation: 39
BODMAS rule buddy!! as the previous answers suggests. Multiplication takes place before your addition. Your opertaion Sqrt(A+1) where A = 10 will evaulate to 10+1*10+1 10+10+1 21!!
Upvotes: 0
Reputation: 40643
Inside the macro, A
is replaced with whatever was passed into the macro invocation. In this case, that is A+1
. This means that the macro gets expanded to:
A+1 * A+1
Due to operator precedence, this is interpreted as A + 1*A + 1
, or 10 + 10 + 1 = 21
.
Upvotes: 2
Reputation:
You define the macro as A * A
. So, Sqrt(A + 1)
expands to A + 1 * A + 1
, which is, due to operator precedence, equal to 2 * A + 1
- you've got 2 * 10 + 1 = 21
.
That's why you should always parenthesize your macros and their arguments:
#define Sqrt(A) ((A) * (A))
By the way, why a macro? What if one day you write Sqrt(A++)
? Then you can expect nasal demons. It would be safer to write an inline function instead (horribile dictu, a correctly named inline function):
static inline double square(double x)
{
return x * x;
}
Upvotes: 3
Reputation: 60037
'cos
#define Sqrt(A) A * A
makes
Sqrt(A+1);
translate to
A + 1 * A + 1
and A is 10
so you get
10 + 1 * 10 + 1
Now do the maths!
BTW sqrt has seems to say square root not squared!
Upvotes: 3