1

I am not able to understand this code

#define sqt(x) x*x
int main(){
print("%d",sqt(3+1));
}

Manually I am getting the output of 10. But when write the code and compile it I am getting the answer as 7. Please explain this.

halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

9

Remember, since you're using a macro, 3 + 1 is not evaluated before sqt is called. x becomes 3 + 1 (not 4), then order of operation causes an unexpected answer to be produced since addition happens after multiplication.

Or in other words:

sqt(3 + 1)

expands to:

3 + 1 * 3 + 1

Then, when you evaluate this like you would any other equation:

3 + 1 * 3 + 1 // Multiplication happens first
= 3 + 3 + 1
= 7

This is a good example of why you shouldn't use macros unless they're strictly necessary, or you've made proper care to ensure that things like order of operation mistakes don't happen. As @Barmar points out this particular case can be remedied by having the macro expand to include explicit parenthesis:

#define sqt(x) ((x)*(x))

Which would cause the evaluation to differ and give a proper answer:

(3 + 1) * (3 + 1)
4 * 4
16
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • You should show how to fix the macro so it works as intended. – Barmar Nov 08 '18 at 01:38
  • This is a good example of why you should write your macros carefully. – Mad Physicist Nov 08 '18 at 01:38
  • @Barmar. Sadly, this macro will never result in 10 :) – Mad Physicist Nov 08 '18 at 01:39
  • 2
    Macros like this are perfectly fine, and there's no reason at all not to use them--as long as you include the parentheses. – Lee Daniel Crocker Nov 08 '18 at 01:39
  • 1
    @LeeDanielCrocker The only reason to use macros like this is because you're using a 30-year-old compiler that doesn't optimize tiny functions by expanding them inline. – Barmar Nov 08 '18 at 01:40
  • @Barmar Honestly, I know macros conceptually very well because of my familiarity with Clojure, but don't know C++ well enough to answer that. You could force order of operation by explicitly adding parenethsis in the macro definition, if that's the fix you're referring to. I suspect though that unless the call overhead really is a concern, a macro shouldn't be used here in the first place. – Carcigenicate Nov 08 '18 at 01:42
  • Exaclty. `#define sqt(x) (x*x)` – Barmar Nov 08 '18 at 01:42
  • 1
    And while they're not really necessary, they're not uncommon, but neither are mistakes like this. – Barmar Nov 08 '18 at 01:43
  • @Barmar Umm, no. Try again. Not nearly enough parentheses. – user3386109 Nov 08 '18 at 01:45
  • 1
    @user3386109 You got me. Macros like this really are a PITA. – Barmar Nov 08 '18 at 01:47
  • @Barmar Yup, which I why I agree with @ Carcigenicate's original advice to avoid macros. And agree with you that it's better to let the compiler inline tiny functions. – user3386109 Nov 08 '18 at 01:49