John
John

Reputation: 151

C program:output seems confusing

#include<stdio.h>  
#include<conio.h>  
#define SQUARE(x) (x*x)  
void main()  
{  
    clrscr();  
    int i=3,j,k;  
    j=SQUARE(i++);  
    k=SQUARE(++i);  
    printf("\n%d\n%d\n%d",j,k,i);  
    getch();  
}  

Answer confusing: 9 49 7 I was thinking j=3*4=12, k=6*7=42 , i=7 What is happening?did i miss something? (x*x)=((x)*(x)) same here.it doesn't matter.

Upvotes: 0

Views: 524

Answers (1)

paxdiablo
paxdiablo

Reputation: 881453

The two lines:

#define SQUARE(x) (x*x)  
j=SQUARE(i++); 

translates into:

j = (i++ * i++);

which is undefined behaviour. You are not permitted to modify a variable twice without an intervening sequence point (and * is not a sequence point).

You're better off using something like:

inline int SQUARE (int x) { return x * x; }

What's probably happening is that the increments are happening together after or before the multiplication is done, effectively giving you:

i = 3;                  // i = 3
j = i * i; i++; i++;    // j = 9, i = 5
++i; ++i; k = i * i;    // i = 7, k = 49

But keep in mind that's what's happening in this case. An implementation is free to do it some other way since you're breaking the rules. In fact, it can format your hard disk if it wants to. That is the nature of undefined behaviour, defined as (my italics):

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements.

NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Upvotes: 8

Related Questions