Assaf Malki
Assaf Malki

Reputation: 303

C Macro Behavior

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

Answers (8)

reshma
reshma

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

Nitin4873
Nitin4873

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

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

Achuthananda MP
Achuthananda MP

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

Mankarse
Mankarse

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

user529758
user529758

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

Ed Heal
Ed Heal

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

Naruil
Naruil

Reputation: 2310

You should define the macro as #define Sqrt(A) ((A) * (A))

Upvotes: 1

Related Questions