tags:

views:

90

answers:

4

Possible Duplicate:
Problem with Macros

Hi all

I have defined this macro:

#define SQ(a) (a*a)

and called it in this way:

std::cout << SQ(2+3) << '\n';

the output was 11. Why ?

Thanks

+5  A: 

Because the expansion of SQ in your example gives:

std::cout << (2+3*2+3) << '\n';

A better way to define the macro would be

#define SQ(a) ((a)*(a))

which solves the precedence issue in this case.

Better still would be to use a function which avoids any issues with the passed expression being evaluated more than once.

E.g. as a template:

template<class T>
T SQ(T a) { return a * a; }
Charles Bailey
+4  A: 

Macros do only simple text manipulation, i.e. they are very stupid that way in that they don't see 'code', only 'text' which are then sent to to the C/C++ parser for validation.

SQ(2+3) becomes (2+3*2+3)

That's why you should use templates, which are a bit smarter, they would do what you expected: first calculate 2+3, then do 5*5.

Gianni
+1 for explaining, -1 since macro are not stupid, they are just what they are: a tool that sometimes is useful, sometimes it is not.
ShinTakezou
I didn't mean that the use of macros is stupid, in fact, the very next response I gave I suggested macros. I mean that macros don't do any smart processing, they are 'stupid' in the sense that they just do text processing; sometimes that might be exactly what we want to do some very smart things..
Gianni
got it: macros are what they are, and the preprocessor works like that, anyway:D stupidity is when Macro thinks to be something different, and try to compare with other tools:D
ShinTakezou
+2  A: 

Fix your macro to:

#define SQ(a) ((a)*(a))
Roku
+1  A: 

Others already have the answer. The "fix" (if you must use macros at all) is to wrap all your params with parens, e.g.

#define SQ(a) ((a)*(a))

In most cases, you're better off using templates as this will still perform compile-time expansion for speed, but also provides language support for syntax and type checking.

holtavolt