-1

I have this function and it adds a number to itself.

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

#define ADD(x)  (x)+(x)
int main()
{
    int x = 2;
    int y = ADD(++x);

    cout << y << endl;
}

When I run this program, it returns 8 but I was expect 6.

I thought x = 3 and it was sending 3 to the ADD function but it seems like it doesn't. Can someone explain it to me?

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
Berkin
  • 1,565
  • 5
  • 22
  • 48
  • What does it return if you just call ADD(2)? – Pike D. Feb 04 '17 at 11:46
  • 2
    It is the old way to create inline function. Try to not do this nowadays. – Piotr Siupa Feb 04 '17 at 11:55
  • 1
    [The need for parentheses in macros in C](http://stackoverflow.com/q/10820340/995714) – phuclv Feb 04 '17 at 12:30
  • In addition to the problem that this code illustrates, consider what happens with an expression like `2 * ADD(3)`. The result is not 12. The macro needs additional parentheses around the entire expression: `((x)+(x))`. – Pete Becker Feb 04 '17 at 13:20

4 Answers4

12

Your program has undefined behaviour, because you are calling the preincrement operator twice: int y = (++x)+(++x);. Didn't you get a compiler warning for that?

The problem is that ADD is not a function. It's a macro; it performs textual replacement. Don't use macros for such things in C++.

If you turn the macro into a function, everything will work fine, because then ++x only appears once:

#include <iostream>

template <class T>
T add(T x)
{
    return x + x;
}

int main()
{
    int x = 2;
    int y = add(++x);

    std::cout << y << '\n';
}
Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
1

It's undefined behavior.

When your compiler preprocesses the macro here:

int y = ADD(++x);

it becomes

int y = (++x)+(++x);

There is no specified order in which arguments are evaluated.

For more information, see Why are these constructs (using ++) undefined behavior?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
msc
  • 33,420
  • 29
  • 119
  • 214
1

Macros are not real C++ functions. It's just text replacing.

Your code:

int y = ADD(++x);

is replaced with:

int y = (++x)+(++x);

You can use a template function instead of the macro.

template<typename T1, typename T2>
inline auto add(T1 x, T2 y)
{
    return x + y;
}
Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
0

Since ADD(x) is actually a macro (as opposed to a real function), ADD(++x) evaluates to (++x) + (++x) which isn't nice at all because this modifies the same variable, x, twice in one statement. The result of such modifications are undefined.

In your compiler's specific case, it incremented the value of x from 2 to 3 and then incremented it from 3 to 4. While reading the value of x in order to perform (x+x), it chose to read the latest value, which is 4.

I'd suggest that you read up about the differences between macros and functions.

Vada Poché
  • 763
  • 5
  • 16