1

Can the following macro bring problems?

#define sq(x) x*x

If yes, then how and why?please help.

joey rohan
  • 3,505
  • 5
  • 33
  • 70

6 Answers6

9

Yes, it can present problems. Other than the obvious fact that macros don't respect namespaces at all (which means you can't call anything else sq), try the following:

int result = sq(4) / sq(4);

You should surround x * x with parenthesis so it becomes ((x) * (x)).

Another problem:

int a = 0;
int result = sq(++a);

This is an inherent problem with macros, and is one reason inline functions should be preferred.

Cornstalks
  • 37,137
  • 18
  • 79
  • 144
4

I'm not going to give you a straight answer (this looks like a homework question), but I'm going to give you an example that will hopefully make you think about it and come up with a correct answer:

#include <iostream>

#define sq_macro(x) x * x

int sq_function(int x)
{
    return x * x;
}

int print_and_ret(int x)
{
    std::cout << x << '\n';
    return x;
}

int main()
{
    std::cout << "Calling sq_macro:\n";
    sq_macro(print_and_ret(10));

    std::cout << "Calling sq_function:\n";
    sq_function(print_and_ret(10));
}

When you run the program, the macro and the function give two different behaviors. Think about what a macro is, and what a function is.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
3

While writing macros use brackets excessively. Rewrite the macro as follows

#define sq(x) ((x)*(x))

If you don't do this then you will have problems in cases where macro is used as sq(5+4)

To understand the problem do macro expansion and see.

CCoder
  • 2,305
  • 19
  • 41
2

As pointed out, you should wrap each use of the argument in parentheses to ensure correct behavior, for example, when the argument is something like i * 2:

#define sq(x) ((x)*(x))

But there is another potential issue. Consider the following:

result = sq(++i);

This is translated to:

result = ((++i)*(++i))

Where as the intention was likely to increment i only once, it gets incremented twice. This is a common side effect for macros.

One approach is just to be aware of this when calling it, but a better one is to put sq() in its own inline function.

Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48
Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
1

All of these can cause trouble:

int x = 12;
int n = sq(x+3);
int y = sq(x++);
int z = 2 * sq(2 + n) * n;

comparared with a function sq.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

For one, operator precedence would be messed up:

sq(2+2); // author wants 4*4, but gets 2+2*2+2. 
juanchopanza
  • 223,364
  • 34
  • 402
  • 480