2

I'm trying to understand this block of code here:

#include <iostream>
using namespace std;

#define mymult(a, b) a*b
inline int mymult1(int a, int b) {return a*b;}

int main() {
cout << "mymult(2+2, 3+3) = " << mymult(2+2, 3+3) << "\n";
cout << "mymult1(2+2, 3+3) = " << mymult1(2+2, 3+3) << "\n";
}

mymult = 11, and mymult1 = 24. I know that '#define's essentially work via call by name, rather than call by value. However, I'm having trouble understanding why the value it returns is 11... and not 24. What causes this?

Tabrock
  • 1,120
  • 1
  • 20
  • 37
  • 7
    `#define` is bacisally name substition, so it transforms into `2+2*3+3` – Predelnik Apr 02 '15 at 19:00
  • @predlnik that is the answer!! – Steephen Apr 02 '15 at 19:03
  • ...which is one of many reasons to prefer inline functions over macros. – Richard Hodges Apr 02 '15 at 19:04
  • ... and **when** using macros to pass each argument within parantheses. – cadaniluk Apr 02 '15 at 19:05
  • ... unless you wish to succeed in obfuscated C-contest.... – BitTickler Apr 02 '15 at 19:07
  • @cad, You totally cannot rely on everyone doing that. If you ever write a macro and expect callers to do that when it would have worked by the macro doing that, it's terrible even by macro standards. – chris Apr 02 '15 at 19:15
  • The best way is to avoid the macros altogether, unless really forced not to. Even with parenthesis etc you can still get into trouble. Example from Scott Meyers' book *Effective C++*, item 3: `#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))` Now do `CALL_WITH_MAX(++a, b)`, and you may end up incrementing `a` twice, in something that looks like perfectly reasonable code. – vsoftco Apr 02 '15 at 19:17
  • possible duplicate of [The need for parentheses in macros in C](http://stackoverflow.com/questions/10820340/the-need-for-parentheses-in-macros-in-c) – Alex Celeste Apr 14 '15 at 17:12

1 Answers1

6

Option 1: In the case of:

#define mymult(a, b) a*b

a and b are treated like place holder strings and when you call mymult, the parameters a and b are just copied as they were written. In other words:

mymult(2+2, 3+3) = 2+2*3+3

where a = 2+2, b = 3+3.

Therefore you may call mymult as follows:

mymult( (2+2), (3+3) )

where a = (2+2), b = (3+3).

This will be interpreted as:

mymult( (2+2), (3+3) ) = (2+2)*(3+3)    

and return the value of 24 as expected.

Option 2: If we are allowed to modify the #define statement then an alternative way of doing this is defining it with the parentheses as follows:

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

This will give the same expected result since a and b will be put directly into the parentheses as they are. In other words:

mymult(2+2, 3+3) = (2+2)*(3+3) = 24

where a = 2+2, b = 3+3.

Option 3: Stick with the inline function as defined in OP:

inline int mymult(int a, int b) {return a*b;}

Good luck!

erol yeniaras
  • 3,701
  • 2
  • 22
  • 40