views:

427

answers:

7
+3  Q: 

C #define macros

Hi. Here is what i have and I wonder how this works and what it actually does.

#define NUM 5
#define FTIMES(x)(x*5)

int main(void)
{

    int j = 1;

    printf("%d %d\n", FTIMES(j+5), FTIMES((j+5)));
}

It produces two integers: 26 and 30. But i can't seem to understand how it makes this possible.. Thanks.

+17  A: 

The reason this happens is because your macro expands the print to:

printf("%d %d\n", j+5*5, (j+5)*5);

Meaning:

1+5*5 and (1+5)*5
Cody Brocious
That should teach a valuable lesson in avoiding #define macros for things that inline functions should actually handle.
Calyth
Or, when you can't avoid them, place each occurrence of each argument in parentheses, and place the entire macro in parenthesis (that is, when your macro is an expression and not a statement)
Arkadiy
A: 

the preprocessor substitutes all NUM ocurrences in the code with 5, and all the FTIMES(x) with x * 5. The compiler then compiles the code.

Its just text substitution.

Megacan
A: 

Order of operations.

FTIMES(j+5) where j=1 evaluates to:

1+5*5

Which is:

25+1

=26

By making FTIMES((j+5)) you've changed it to:

(1+5)*5

6*5

30

Eddie Parker
+2  A: 

The compiler pre-process simply does a substitution of FTIMES wherever it sees it, and then compiles the code. So in reality, the code that the compiler sees is this:

#define NUM 5
#define FTIMES(x)(x*5)

int main(void)
{

    int j = 1;

    printf("%d %d\n", j+5*5,(j+5)*5);
}

Then, taking operator preference into account, you can see why you get 26 and 30.

casperOne
Technically, the compiler doesn't see the #defines. :)
Greg Hewgill
+3  A: 

define is just a string substitution.

The answer to your question after that is order of operations:

FTIMES(j+5) = 1+5*5 = 26

FTIMES((j+5)) = (1+5)*5 = 30

Joe
+12  A: 

Since it hasn't been mentioned yet, the way to fix this problem is to do the following:

#define FTIMES(x) ((x)*5)

The parentheses around x in the macro expansion prevent the operator associativity problem.

Greg Hewgill
that won't save you if you have multiple occurrences of the parameter in the macro and you pass in some kind of expression with side effects, like j += 3.
rmeador
+1  A: 

And if you want to fix it:

#define FTIMES(x) ((x) * 5)
Sean Bright