0

I wanted to use this logic to find the largest of three numbers. However, my code does not compile and I don't understand the compiler message. How do I fix the code?

#include <stdio.h>

#define LARGE(a, b, c){ \
        int max = 0, a, b, c;\
        max = ( (a+b) + abs(a+b)/2 ); \
        max = (max + c) + abs(max+c)/2);}


int main(void) {
    int a, b, c, max, Result;
    
    scanf("%d%d%d", &a, &b, &c);
    
    Result = LARGE(a, b, c);
    printf("%d", Result);
    
    return 0;
}

output is

ain.c:12:12: error: expected expression
    Result=LARGE(a,b,c);
           ^
main.c:2:21: note: expanded from macro 'LARGE'
#define LARGE(a,b,c){ \
                    ^
1 error generated.
E_net4
  • 27,810
  • 13
  • 101
  • 139
  • *I don't know what happaned*. Please show the errors or describe any incorrect behaviour that is leading you to ask this question. For starters, declaring new variables in the macro with the same names as the macro parameters is probably not right. – kaylum Feb 18 '21 at 08:09
  • 1
    Also, you are using the macro to assign to a variable. But the macro is a compound expression and that can't be assigned to a variable. – kaylum Feb 18 '21 at 08:13
  • Why on earth do you want to use a macro for this? What's wrong with using a function? And the logic you use, seems pretty inefficient to me. – Jabberwocky Feb 18 '21 at 08:28
  • @Jabberwocky actually it was given in my college they were teaching the macros. Hmm you are right logic is pretty bad. :) – sumit patil Feb 18 '21 at 08:36
  • @Jabberwocky you know why, a function always depends on the type while a macro substitutes the parameters regardless of the type passed, although it is considered very bad practice to hide the code behind a macro, this is the obvious advantage. – David Ranieri Feb 18 '21 at 09:46
  • @Jabberwocky THANKS, MATE :) i am getting more knowledge from stackoverflow. more than my class. – sumit patil Feb 18 '21 at 11:37

2 Answers2

2

Using a macro is not the same as using a function. The macro is expanded before compilation. So when you define a macro you just substitute some code with a smaller one that can eventually be reused in other part of your code. In your case, this should contain code that can be put after "Result=".

#define LARGE(a,b,c){ \
        int max=0,a,b,c;\
        max=((a+b)+abs(a+b)/2); \
        max=(max+c)+abs(max+c)/2);} 
Result=LARGE(a,b,c)

is equivalent to write :

Result={ \
        int max=0,a,b,c;\
        max=((a+b)+abs(a+b)/2); \
        max=(max+c)+abs(max+c)/2);}

Which would not compile. You should have write your macro as :

#define LARGE(a,b,c) (((a+b)+abs(a+b)/2)+c)+abs(((a+b)+abs(a+b)/2)+c)/2) 

Eventually you could had another macro :

#define MAX(a,b) ((a+b)+abs(a+b)/2)
#define LARGE(a,b,c) (MAX(a,b)+c)+abs(MAX(a,b)+c)/2)
Ptit Xav
  • 3,006
  • 2
  • 6
  • 15
1

Those variables a, b, c, max are already declared in main, don't redeclare them in the body of the macro, also, always prefer:

#define macro(x) do { body } while (0)

over

#define macro(x) { body }

see why: do { ... } while (0) — what is it good for?

Finally, your implementation using abs to get the largest of three numbers seems broken, this works (passing max as a reference):

#include <stdio.h>

#define LARGE(a, b, c, max)             \
do {                                    \
    if ((a) >= (b) && (a) >= (c))       \
        *(max) = (a);                   \
    else if ((b) >= (a) && (b) >= (c))  \
        *(max) = (b);                   \
    else                                \
        *(max) = (c);                   \
} while (0)

int main(void)
{
    int a, b, c, max;

    scanf("%d%d%d", &a, &b, &c);
    LARGE(a, b, c, &max);
    printf("%d\n", max);
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • I disagree, you should _not_ use `do while(0)` unless you have specialized requirements such as exposing the macro as part of some portable library. See [What is do { } while(0) in macros and should we use it?](https://software.codidact.com/posts/279576). I was once pushing for MISRA-C to drop the do while(0) recommendation since MISRA-C requires {} after all selection/iteration statements and then do while(0) is just harmful since it hides bugs. And the advise to use do while(0) when writing macros was dropped in MISRA-C. They used it in the 2004 version but dropped it in the 2012 version. – Lundin Feb 18 '21 at 08:58
  • @DavidRanieri It should be avoided to give a compiler error when you use `if(...) MACRO(); else` instead of the safer form `if(...) { MACRO(); } else`. – Lundin Feb 18 '21 at 09:41