2

I am new to c language. I just wanted to know why is my macro not working properly. It is giving me output as 13 where as my expected output is 24.?

#include<stdio.h>
#define mult(a,b) a*b
int main()
{
    int x=4,y=5;
    printf("%d",mult(x+2,y-1));
    return 0;
}
2
  • 5
    Pipe it through the preprocessor, apply elementary maths, then regret not having obeyed to the rule "always parenthesize macro arguments". Oh, and next time think twice before using a macro. And then don't use a macro but write a (possibly inline) function instead. Commented Jul 9, 2013 at 16:05
  • 1
    It needs to be #define mult(a,b) ((a)*(b)). That is causing the problem. Commented Jul 9, 2013 at 16:09

4 Answers 4

6

mult(x+2,y-1) expands to x +2 * y -1 that is equals to 4 + 2 * 5 -1 gives output: 13.

You might be expecting answer (4 + 2) * (5 -1) = 6 * 4 = 24. To make it expand like this you should write parenthesize macro as @H2Co3 also suggesting:

#define mult(a,b) ((a)*(b))

Read aslo: So, what's wrong with using macros? by Bjarne Stroustrup.

Sign up to request clarification or add additional context in comments.

1 Comment

It should be ((a)*(b))
5

This is because C macros are simple textual substitutions, the macro writer must be sure to insert parentheses around every macro variable when it is substituted, and around the macro expansion itself, to prevent the resulting expansion from taking on new meanings.

If you observe your program: mult(a, b) is defined as a * b

mult(x + 2, y - 1) = x + 2 * y - 1 = 4 + 2 * 5 - 1 = 4 + 10 - 1 = 13

The Correct way would be:

mult(a, b) ((a) * (b))

2 Comments

No you didn't. It should be ((a)*(b))
@AseemBansal did it! :)
2

Use parentheses in the macro definition

#include<stdio.h>
#define mult(a,b) ((a)*(b))
int main()
{
    int x=4,y=5;
    printf("%d",mult(x+2,y-1));
    return 0;
}

This is because different arithmetic operators have different precedence levels. Hence always use parentheses while defining the macro.

Comments

2

Because it replaces the arguments literally:

mult(x+2,y-1) --> mult(4+2,5-1) --> 4 + 2*5 - 1 --> 13

Try changing the define to:

#define mult(a,b) (a)*(b)

In this case the result after pre-processing is this:

int main()
{
    int x=4,y=5;
    printf("%d",(x+2)*(y-1));
    return 0;
}

This will solve the problem but it's still not the best way to do it.

#define mult(a,b) ((a)*(b))

This version is considered as good practice because in other types of situation the first one would fail. See the bellow example:

#include<stdio.h>
#define add(a,b) (a)+(b)
int main()
{
    int x=4,y=5;
    printf("%d",add(x+2,y-1)*add(x+2,y-1));
    return 0;
}

In this case it would give an incorrect answer because it is translated by the pre-processor to the fallowing:

int main()
{
    int x=4,y=5;
    printf("%d",(x+2)+(y-1)*(x+2)+(y-1));
    return 0;
}

printing 34 instead of 100.
For the ((a)+(b)) version it would translate to:

int main()
{
    int x=4,y=5;
    printf("%d",((x+2)+(y-1))*((x+2)+(y-1)));
    return 0;
}

giving a correct answer.

4 Comments

Nah. Try changing it to ((a)*(b)) in order to get used to the habit of always parenthesizing everything.
No. That's not a good reason. Habits unjustified and not explained properly don't hold.
@iionela.voinescu -- euh, unjustified? Why? Isn't this very question enough justification? Also, read this, there are plenty of good reasons in there to parenthesize stuff.
The user how posted the question said he is new to programming in C. I don't need your comment to be explained to me, but he might. Instead of just saying that's a good habit you should have explained why that is, properly, in a separate answer. Things like these always remain better in someone's mind if they are properly explained.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.