3

I have written the following C program. The output is 32. Why is this?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define max 10+2

int main(){
    int i;
    i = max * max;
    printf("\n%d\n",i);

    return 0;
}

(I am learning C and am relatively new to it.)

AstroCB
  • 12,337
  • 20
  • 57
  • 73
karan421
  • 863
  • 17
  • 43
  • 1
    Does it help if I tell you that what the compiler actually sees is "`i=10+2*10+2;`"? – zwol Mar 26 '12 at 03:24

4 Answers4

6
#define max 10+2

This is the preprocessor. it is not smart.

it is stupid.

it just replaces text.

max*max

will resolve to

10+2*10+2

which is

10+(2*10)+2

because of operator precedence, which is

10 + 20 + 2

i.e. 32

Furthermore, you should avoid preprocessor macros whenever you can and use static const instead. You may or may not want to also consider using a const variable or an enum instead of a #define; each have their tradeoffs, refer to the similar question: "static const" vs "#define" vs "enum".

If you want to stick to preprocessor, then you could just use:

#define max (10+2)

Since parenthesised code will take operator precendence.

Community
  • 1
  • 1
Preet Kukreti
  • 8,417
  • 28
  • 36
  • 4
    Final line is bad advice. In C, a `static const` variable is worse (as a constant) than a preprocessor macro in every single way. The problem is easily solved by adding the correct parentheses to the macro. – R.. GitHub STOP HELPING ICE Mar 26 '12 at 03:49
  • @R.. can you please explain why it is worse. – Preet Kukreti Mar 26 '12 at 03:56
  • The bigges one is that it's not a constant expression, so it can't be used in contexts where a constant expression is required - not even as an initializer for other `static const` objects. – R.. GitHub STOP HELPING ICE Mar 26 '12 at 04:41
  • 2
    It is not worse than a macro in every single way, there are plenty of cases where it is better than a macro. Perhaps you want to keep track over how much memory all your const data consumes. Or perhaps you want to keep all const that in a particular segment of ROM. static const is also type safe, #define:d literals are not, they are always (signed) int. And a static const does not needlessly clutter down the global namespace. If "max" in this post isn't going to be used as an initializer, I think it would be better off declared as static const. – Lundin Mar 26 '12 at 11:18
2

Since max is a macro, it gets expanded textually, so your code comes out with:

i = 10 +2 * 10 + 2;

For a macro like this, you generally want to add parentheses:

#define max (10+2)

So your expression will expand to:

i = (10+2) * (10+2);
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

The compiler sees this

i = 10 + 2*10 +2 = 32

You should do the macro definition like this

#define max (10+2)
0

Operator precedence is a funny thing. PEMDAS = Parenthises, Exponents, Multiply, Divide, Add, Subtract.

This is going to resolve to equal to 10 + (2 * 10) + 2. First is 10*2 which equals 20.

Now it reads 10 + 20 + 2. The rest should be clear.

You should exercise control over your arithmetics whenever desired.

aa4522ff
  • 51
  • 9