Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
1.80/5 (2 votes)
See more:
C
#include <stdio.h>
#define PRODUCT(x) ((x)*(x))
int main()
{
    int i=3,j,k;
    j=PRODUCT(i++);
    k=PRODUCT(++i);
    printf("%d %d",j,k);
    return 0;
}
Posted
Updated 4-Nov-15 4:22am
v2
Comments
Thomas Daniels 4-Nov-15 10:36am    
Are you sure it outputs 9? When I ran it, I got 12. (I know why this happens, but if your first output is actually 9 then I have no idea because I would actually expect 12 here -- I'll answer if you can confirm that it's actually 12.)
Leo Chapiro 4-Nov-15 10:41am    
Yes, take a look: http://codepad.org/2FyKYfmW
Thomas Daniels 4-Nov-15 10:46am    
Huh, that's weird, because I get: http://ideone.com/FKOnAE
Leo Chapiro 4-Nov-15 10:58am    
Yes, this is crazy! :) I have debugged with Visual Studio 2012 and got the same results (9 and 49).
Richard Deeming 4-Nov-15 11:43am    
At a guess, one version is getting the value of x once, incrementing it twice as _duDE_ described, then returning 3 * 3.

The other is getting the value of x, incrementing it, getting the value of x again, incrementing it again, then returning 3 * 4.

It's probably one of those areas where the behaviour is "undefined", so if you feed the same code to three different compilers, you get five different results. :)

1 solution

We can go through this code step-by-step:

int i=3,j,k;

The variables are declared, the "i" has value of 3.

j=PRODUCT(i++);

The macro PRODUCT is called, the value of "i" is first 3 and 3*3 = 9.
Now after this the value of "i" will be incremented twice because of (x)*(x)!
The value of "i" is now 5.

k=PRODUCT(++i);

The macro PRODUCT is called but before the value of "i" will be incremented twice because of (x)*(x) and is 7 and 7*7 = 49.
 
Share this answer
 
Comments
Krunal Rohit 4-Nov-15 11:45am    
You're on fire _duDe_. 5!

-KR
Leo Chapiro 4-Nov-15 12:14pm    
Thank you! :)
Anupkumar_vj 4-Nov-15 11:57am    
i++*i++ means 3++*3++=3*3=9, i has incremented to 5. Now ++i*++i means ++5*++5=6*7=42 know ?
Dave Kreskowiak 4-Nov-15 12:25pm    
No, the value of i is evaluated after all references to it have been "incremented". At the start of the your second call in the PRODUCT macro, NOT A FUNCTION CALL!, your code is actually k = (++i) * (++i). Both of the i variable references will be incremented BEFORE the expression starts to be evaluated. So your code is incrementing i twice, once for each mention of it, before the math expression is evaluated. Your assignment to k is actually k = 7 * 7, NOT k = 6 * 7.
Dave Kreskowiak 4-Nov-15 12:26pm    
Here's the ASM code for it, if you care to read it:
_k$ = -32 ; size = 4
_j$ = -20 ; size = 4
_i$ = -8 ; size = 4
_main PROC ; COMDAT

; 9 : {

push ebp
mov ebp, esp
sub esp, 228 ; 000000e4H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-228]
mov ecx, 57 ; 00000039H
mov eax, -858993460 ; ccccccccH
rep stosd

; 10 : int i=3,j,k;

mov DWORD PTR _i$[ebp], 3 ; Store 3 in i.

; 11 : j=PRODUCT(i++);

mov eax, DWORD PTR _i$[ebp] ; Copy i to EAX
imul eax, DWORD PTR _i$[ebp] ; Integer Multiply i by EAX (3 * 3) and store result in EAX.
mov DWORD PTR _j$[ebp], eax ; Copy EAX to J (value is 9).
mov ecx, DWORD PTR _i$[ebp] ; Copy i to ECX (value is 3).
add ecx, 1 ; Add 1 to ECX.
mov DWORD PTR _i$[ebp], ecx ; Copy ECX to i (value is 4).
mov edx, DWORD PTR _i$[ebp] ; Copy i to EDX (value is 4).
add edx, 1 ; Add 1 to EDX.
mov DWORD PTR _i$[ebp], edx ; Copy EDX to i (value is 5).

; 12 : k=PRODUCT(++i);

mov eax, DWORD PTR _i$[ebp] ; Copy i to EAX (value is 5).
add eax, 1 ; Add 1 to EAX.
mov DWORD PTR _i$[ebp], eax ; Copy EAX to i (value is 6).
mov ecx, DWORD PTR _i$[ebp] ; Copy i to ECX (value is 6).
add ecx, 1 ; Add 1 to ECX.
mov DWORD PTR _i$[ebp], ecx ; Copy ECX to i (value is 7).
mov edx, DWORD PTR _i$[ebp] ; Copy i to EDX (value is 7).
imul edx, DWORD PTR _i$[ebp] ; Integer Multiply i by EDX (7 * 7) and store result in EDX.
mov DWORD PTR _k$[ebp], edx ; Copy EDX to k (value is 49).

; 13 : printf("%d %d\r\n",j,k);

mov esi, esp
mov eax, DWORD PTR _k$[ebp]
push eax
mov ecx, DWORD PTR _j$[ebp]
push ecx
push OFFSET ??_C@_07BMEMJKJN@?$CFd?5?$CFd?$AN?6?$AA@
call DWORD PTR __imp__printf
add esp, 12 ; 0000000cH
cmp esi, esp
call __RTC_CheckEsp

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900