-7
#include <stdio.h>

#define F1(X) ((X > 0) ? X : -(X))
#define F2(X) (X > 0) ? X : -X

int main(){
    int a=5, b=10;
    printf("F1=%d, F2=%d\n", F1(a-b), F2(a-b));
    return 0;
}

The output is: F1=5, F2=-15

Of course, I'd think that the output of F1 and F2 should be the same. What do the parentheses have anything to do with the output?

kiraleos
  • 49
  • 1
  • 5
  • Difference between a function and text substitution. Very instructive. – stark Feb 23 '18 at 14:11
  • Macros are textually substituted, do the substitution yourself, and you'll see why the parentheses have an influence. – Jabberwocky Feb 23 '18 at 14:11
  • `-(5 - 10)` versus `-5 - 10`. – Lundin Feb 23 '18 at 14:12
  • @stark What a wonderfully informative answer... – kiraleos Feb 23 '18 at 14:13
  • It's not an answer, it is a comment. You can answer this yourself if you just realize that macros is nothing but text replacement. Any beginner level C book addresses the macro parenthesis issue, so I would suggest reading one. After that, the answer is trivial. – Lundin Feb 23 '18 at 14:14

3 Answers3

1

This program is a simple demonstration of why you always need to parenthesize macro parameters when you use them in expressions. It also illustrates a broader point of why you need to be very careful with macros in general.

I'd think that the output of F1 and F2 should be the same

Had F1 and F2 been functions, not macros, the output would indeed be the same. However, macros are simple textual substitutions, so the two expressions that you get with and without parenthesizing of X are different:

F1:

((a-b > 0) ? a-b : -(a-b))

F2:

(a-b > 0) ? a-b : -a-b

Note that due to lack of parentheses F2 applies unary minus to a, not to (a-b).

This remains a relatively simple use of macros. Imagine the problems you would get in case when X is substituted for an expression with side effects, as in F2(a++, b--).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

While playing with MACRO be careful of parenthesis(). After macro replacement it looks like this

 printf("F1=%d, F2=%d\n", ((a-b > 0) ? a-b : -(a-b)), (a-b > 0) ? a-b : -a-b);

Now calculate.

F1 => ((a-b > 0) ? a-b : -(a-b))
   => ((5-10 >0) ? 5-10 : -(5-10))
   => ((-5>0 ) false so it prints -(5-10) which is 5

and

  F2 => (a-b > 0) ? a-b : -a-b
     => (5-10 >0) ? 5-19 : -5-10
     => -5>0 false so it prints -15
Achal
  • 11,821
  • 2
  • 15
  • 37
0

you should be careful with macros :

F1(a-b), F2(a-b)

turns to :

#define F1(X) ((X > 0) ? X : -(X))
#define F2(X) (X > 0) ? X : -X

int main(){
    int a=5, b=10;
    printf("F1=%d, F2=%d\n", 
                  ((a-b > 0) ? a-b : -(a-b)),
                  (a-b > 0) ? a-b : -a-b ); // < see here
    return 0;
}

in macros if you expect expression as param you should put them in parentheses (exp)

nullqube
  • 2,959
  • 19
  • 18