Shantanu Singh
Shantanu Singh

Reputation: 355

Taking macro argument inside a different macro in C

Why this is not giving the desired output ? For Ex - take a=1,b=2,c=3,d=4 It is giving MAX4() = 2 while it should be 4 in this case.

#include<stdio.h>
#define MAX4(a,b,c,d) MAX2(MAX2(a,b),MAX2(c,d))
#define MAX2(a,b) a>b?a:b 

int a,b,c,d;

int main(){

    /*printf("Please enter 2 integers - \n");
    scanf("%d %d",&a,&b);   
    printf("The maximum number among them is %d\n",MAX2(a,b));
    */
    printf("Please enter 4 integers - \n");
    scanf("%d %d %d %d",&a,&b,&c,&d);   
    printf("The maximum number among them is %d\n",MAX4(a,b,c,d));//,MAX2(a,b),MAX2(c,d));

    return 0;
}

Upvotes: 1

Views: 253

Answers (3)

Subhiksh
Subhiksh

Reputation: 301

In your macro

MAX4(a,b,c,d);

if a=1, b=2, c=3, d=4 then the macro becomes

MAX4(1,2,3,4);

which would in turn will become

MAX2(MAX2(1,2),MAX2(3,4))

So it is evaluated as

MAX2(1>2?1:2,3>4?3:4) 

i.e

1>2?1:2>3>4?3:4?1>2?1:2:3>4?3:4

and and according to operator precedence and associativity you get 2 and not 4.

In order to get 4 you should use

#define MAX2(a,b) ((a)>(b)?(a):(b)) 

Upvotes: 2

Chris Dodd
Chris Dodd

Reputation: 126546

Macros just do text replacement. So the MAX4 call first expands macros in its arguments, giving

    MAX2(a>b?a:b,c>d?c:d)

which then expands to

    a>b?a:b>c>d?c:d?a>b?a:b:c>d?c:d

When the compiler then parses the expanded macro, the precedence of > (higher than ?:) causes this to not do what you expect. Using extra parentheses in the macro can avoid the precedence problem, but you may still have problems if you call your MAX2 macro on expressions with side effects.

Upvotes: 3

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136525

You need to add parenthesis to enforce the order of evaluation:

#define MAX2(a,b) ((a)>(b)?(a):(b)) 

The extra parenthesis around arguments are needed to allow for expressions like MAX2(a + 1, b + 2).

Upvotes: 3

Related Questions