Max
Max

Reputation: 1213

c++ macro sideeffect

I don't understand why the result is going to be 36. Can somebody explain to me what is happening here and what the preprocessor does?

#include <iostream>
#define QUADRAT(x) ((x) * (x))

using namespace std;

int main()
{
    double no = 4.0;
    double result = QUADRAT(++no);

    cout << result;
    return 0;
}

Thanks alot :>

Upvotes: 0

Views: 412

Answers (4)

DataPlusPlus
DataPlusPlus

Reputation: 1120

This line:

double result = QUADRAT(++no);

gets expanded to this:

double result = ((++no) * (++no));

The way that this ends up running is equivalent to:

no = no + 1;
no = no + 1;
result = no * no;

It runs this way because the increments are performed before the multiplication: the preprocessor does a textual copy of what you pass it, so it copies the "++no" so that it shows up twice in the final code, and the increment of each ++no happens before the result is computed. The way to fix this is to use an inline function:

inline double QUADRAT(double x) { return x * x; }

Most modern compilers will expand this code out without doing a textual substitution - they'll give you something as fast as a preprocessor definition, but without the danger of having issues like the one you are facing.

Upvotes: 1

ShinTakezou
ShinTakezou

Reputation: 9671

What happens is a sort of literal substitution of ++no in place of x, it is like you have written:

double result = ((++no) * (++no));

What is the result... it should be undefined behaviour (you get 36 by chance), and g++ with -Wall agrees with me.

Upvotes: 0

Seth Carnegie
Seth Carnegie

Reputation: 75150

The preprocessor will replace QUADRAT(++no) with ((++no) * (++no)) in that example.

That would increment no twice, if it weren't for the fact that there are no sequence points between the two increments, so you are actually causing undefined behaviour. Any output you see is valid because no one can tell what will happen.

Upvotes: 4

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272657

The preprocessor is a basically a copy-and-paste engine. Note that a macro is not a function; instead, it's expanded inline. Consider what happens to your code when the macro is expanded.

Upvotes: 2

Related Questions