-1

I dont understand why the output of this code is 4 and not 16, Assuming that unsigned int takes 4 bytes and long int takes 8 bytes. Any help?

#include <stdio.h>

struct test {
    unsigned int x;
    long int y : 33;
    unsigned int z;
};

int main()
{
    struct test t;
    unsigned int* ptr1 = &t.x;
    unsigned int* ptr2 = &t.z;
    printf("%d", ptr2 - ptr1);
    return 0;
}
wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • 3
    I believe `ptr2 - ptr1` is strictly speaking undefined behavior as they are not two pointers pointing at the same array. Although if you cast to a character type it should be ok and then you get the size in bytes too. – Lundin Jan 20 '23 at 15:13
  • The C standard does not require the type used for declaring a bit-field to have any effect on either the semantics of the bit-field (how it behaves in expressions) or the size of storage used to hold it, except that `_Bool` bit-field acts like a `_Bool`. Even if `long int` is 8 bytes, your `long int y : 33` bit-field is allowed to take fewer or more bytes. – Eric Postpischil Jan 20 '23 at 15:31
  • But wait, there is more! The offset between 2 struct member also depends on struct packing. Which is controlled by compiler arguments. Use "pack 8" and see. – Agent_L Jan 20 '23 at 16:34

1 Answers1

3

I assume you expected the output to be 16, because the offset between the pointers should be 16 bytes (assuming sizes are as you mentioned in your question).

But in c when you subtract pointers, you don't get the number of bytes but the number of elements. The elements are the data the pointers point to.
Since these are unsigned int pointers, and assuming sizeof(unsigned int) is 4, the difference between thr pointers is 4 elements.

However - as @Lundin commented above this theoretical claculation is not really relevant because subtrating pointers that do not point the same array is UB (undefined behavior).

BTW - Note when you add an integral value to a pointer, a similar thing happens on the other way: the result is the address of the pointer plus the integral value times the size of the element pointed by the pointer. E.g.: if you add 1 to unsigned int* ptr1, the resulting address will be higher than ptr1 by 4.

wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • Hello, thank you for the response, but i dont understand what do you mean by elements? – Ismail Kazdar Jan 20 '23 at 15:18
  • Elements are what the pointers point to (in your case `unsigned int` values). This might be clearer when you consider the case when you add e.g. 1 to a `unsigned int` pointer. In this case the address will be incremented by 4. – wohlstad Jan 20 '23 at 15:19