views:

236

answers:

13

HI all,

This is a normal C routine program which i found out in some question bank. It is shown below:

#define CUBE(p) p*p*p

main()
{
    int k;
    k = 27 / CUBE(3);
    printf("%d", k);
}

As per my understanding and knowledge the value of K should be 1 as CUBE(3) would be replaced by 3*3*3 during preprocessing and after the subsequent compilation it would be giving the value of 1, but instead it has shown the value of 81 which has made me curious to know how it happened. Can anyone please justify the answer of 81 to this question above.

+15  A: 

The preprocessor merely substitutes

CUBE(3)

with

3*3*3

So you end up with:

k=27/3*3*3

Which, evaluated left-to-right with operator precedence, is in fact 81.

If you add parenthesees around the macro, you should find the results are correct:

#define CUBE(p) (p*p*p)

It would be even better to surround each instance of p with parenthesees as well, as in:

#define CUBE(p) ((p)*(p)*(p))

Which will allow you to pass expressions to the macro correctly (for example, 1 + 2).

James McNellis
Or, better, `#define CUBE(p) ((p)*(p)*(p))`
Alok
I'd actually make it:#define CUBE(p) ((p)*(p)*(p))But even that's bad, if p is a function call. It may inadvertently get called 3 times.
jm
wow...Thats jst the game of operator precedence.Thanks James and Alok.
maddy
That's why the convention is to use UPPERCASE for macros - so that you realise that they may evaluate their arguments more than once.
caf
+4  A: 
     #define CUBE(p) p*p*p
     main()
     {
        int k;
        k=27/CUBE(3);
        printf("%d",k);

     }

As per my understanding and knowledge the value of K should be 1 as CUBE(3) would be replaced by 3*3*3 during preprocessing

YES

and after the subsequent compilation it would be giving the value of 1,but instead it has shown the value of 81 which has made me curious to know how it happenned.

NO,

k= 27/3*3*3 

 =(((27/3)*3)*3) (The precedence of `*` and `/` are same but the associativity is from left to right)
 =((9*3)*3) =81

Replace #define CUBE(p) p*p*p with #define CUBE(p) ((p)*(p)*(p))

Prasoon Saurav
Thanks a lot everybody
maddy
+3  A: 

Preprocessors should be parenthesized properly. Replace it with

#define CUBE(p) ((p)*(p)*(p))

and see.

shinkou
And beware, even this is broken for CUBE(++i) or CUBE(f(x))
Michael Anderson
that would be UB
fahad
+1  A: 

Your macro is not protected. Try

#define CUBE(p) ((p)*(p)*(p))

The current macro was expanded to

k=27/3*3*3

which is ((27/3)*3)*3

eyalm
A: 
k=27/CUBE(3);  =>   k=27/3 * 3 * 3;

Do you see it? CUBE should be defined like this instead:

#define CUBE(p) ((p)*(p)*(p))
Sudhanshu
A: 

When you do macros, you have to be careful about how you place parentheses. In this case, you don't have any, so the expression becomes 27/3*3*3, which by the precedence rules of / and * becomes (27/3)*3*3.

Mark Ransom
+2  A: 

C macros do textual substitution (i.e. it's equivalent to copying and pasting code). So your code goes from:

k=27/CUBE(3);

to

k=27/3*3*3;

Division and multiplication have the same precedence and have left-to-right associativity, so this is parsed as:

k=((27/3)*3)*3;

which is 9 * 3 * 3 = 81.

This is why C macros should always be defined with liberal use of parentheses:

#define CUBE(p) ((p) * (p) * (p))

For more information, see http://c-faq.com/cpp/safemacros.html from the comp.lang.c FAQ.

jamesdlin
A: 

27/3*3*3 = 9*3*3 = 81 ?

littlegreen
+2  A: 

Because macros are a textual substitution, that works out to:

k = 27 / 3 * 3 * 3;

Since multiplication and division happen left to right, that works out to:

k = ((27 / 3) * 3) * 3;

So, you want to change that in two ways:

#define CUBE(p) ((p)*(p)*(p))

The outer parentheses cause the multiplications to be done before any other operations.

The parentheses around the individual p's are for the case where you do:

CUBE(1 + 2);

Without those inner parentheses, operator precedence will trip you up.

R Samuel Klatchko
A: 

Both / and * operators have the same precedence. To execure 3*3*3 first, you shoudl enclose them in parenthesis.

#include <stdio.h>

#define CUBE(p) p*p*p

int
main ()
{
  int k;
  k=27/(CUBE(3));
  printf("%d",k);
  return 0;
}
Vijay Mathew
+4  A: 

Because of operator precedence 27/3*3*3 = 81

You could use instead:

inline int cube(int p) { return p*p*p; }
stefanB
A: 

its the way in which the associativity and precedence of operators is implemented. when the expression is expanded it becomes 27/3*3*3 and not 27/(3*3*3) now, division and multiplication both have the same precedence in C but the associativity is left to right for both. so it can be shown as : (27/3)*3*3 which in turn equals (9*3)*3 = 81 also, if u remember the old arithmetic rule of BODMAS(Bracket Off Division Multiplication Addition Subtraction), this is the order of precedence, then we do division first and then multiplication. so again we get answer as 81 for 27/3*3*3.

mkamthan
A: 

Hi answer for this is:81 Explanation: In step k=27/cube(3) cube(3) is replaced by 3*3*3 by preprocessor.then above statement becomes as k=27/3*3*3 in that 27/3 expression is evaluated by c compiler(operator precedence) the result is(27/3) :9 the statement k=27/3*3*3 becomes as k=9*3*3; the result for above statement is 81:

satosj