0

Given below is the code. Can someone explain the logic behind it.

#include<stdio.h>

int main() 
{
    int *i,*j;
    i=(int *)60;
    j=(int *)20;
    printf("%d",i-j);
    return 0;    
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Akshit
  • 103
  • 5
  • 1
    `i - j` is pointer difference, size of int in your system is 4 bytes, value-wsie diffidence is `40` that is `10` * `sizeof(int)` , 10 location far to each other. – Grijesh Chauhan Jul 22 '13 at 16:58
  • 2
    Why you people are upvoting this? –  Jul 22 '13 at 17:00
  • Also, the program invokes undefined behavior if `60` and `20` are not valid addresses. –  Jul 22 '13 at 17:01
  • You should use `%td` instead of `%d`, `%td` is the format specifier for the pointer arithmetic. – nouney Jul 22 '13 at 17:38
  • @H2CO3 Does it invoke undefined behavior, when the punned-pointers are never dereferenced? Or was the code changed at some point...? I guess, maybe it does, given the "pointer arithmetic between pointers in unrelated arrays is undefined" case, but I think in this particular case "undefined" will still do something "reasonable"... – twalberg Jul 22 '13 at 20:37
  • Yes, even if you never dereference the pointers, that's still Undefined Behavior. – This isn't my real name Jul 22 '13 at 20:46
  • @twalberg "Does it invoke undefined behavior, when the punned-pointers are never dereferenced?" - yes, as I stated, "if 60 and 20 are not valid addresses". Pointer arithmetic on invalid pointers invokes UB. - "but I think in this particular case "undefined" will still do something "reasonable"." - maybe it will. I would also kind of expect it to print something logically predictable on some systems, but complete garbage or crashes on others. –  Jul 22 '13 at 20:46

6 Answers6

9

You're assigning the pointers values of 60 and 20.

Since int* (pointers), on your platform are 4 bytes each (32bit), and there is a difference of 40 bytes between j and i, i-j returns 40 / sizeof(int), which prints 10.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
5

It's because of the pointer arithmetic. When you add some value to a pointer, the result will depend of the type of the pointer. On your system, sizeof(int) seems to be equal to 4 bytes, so when you do :

int    *p = 0x1000; //totally dumb value, just for example
printf("%p\n", p + 1);

This will print 0x1004.

So : (int*)60 - (int*)20 = 10, because 10 * 4 (the size of int on your system).

nouney
  • 4,363
  • 19
  • 31
  • 1
    @ReedCopsey No, that is incorrect. The base type of the pointer is what matters. –  Jul 22 '13 at 17:02
1

Distance between two pointers of type T is calculated nearly as (a - b) / sizeof (T). If you say

int* a = 0xdeadbeef;
int* b = a + 1;

then numeric distance between a and b will be sizeof(int) (generally 4) but not 1. And in case

char* x = 0x12345678;
char* y = x + 1;

distance will be exactly 1.

Ivan Smirnov
  • 4,365
  • 19
  • 30
0

i and j are pointers to ints. On a 4 byte machine, ints are 4 bytes long, and the difference between the pointer 2 to consecutive ints will be 4. 60 - 20 / 4 is - err - 10

Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
0

Well i guess you got an answer but here is the title; you have to consider the size of the variable, which means, in this case that sizeof(int)==4. so 40 bytes equal to 10 int's(in your operation system).

-1
60-20 => 40 bytes.
sizeof(int *) = 4 bytes.
i => int *; j=int*

So, when you do 60-20, you are doing (int * - int *) i.e. how many int * are in 60-20?

60-20 = 40 
40/4 => 10.

NOTE: assumption is that sizeof(int *) is 4 bytes.

lsk
  • 532
  • 4
  • 5
  • 1
    "i.e. how many int * are in 60-20?" - no, it counts how many `int`s there are. "assumption is that sizeof(int *) is 4 bytes." - that's irrelevant, `sizeof(int)` is what matters. –  Jul 22 '13 at 17:03
  • What I meant to say was how many jumps will the pointer take i.e. how many ints will it have to jump over. But, post your comment, I can see how it can be misleading. Thanks for the correction. I like your precise definition. – lsk Jul 22 '13 at 20:26