4
struct check{
unsigned short a;
unsigned short b;
};

static unsigned char v[5] = {1,2,3,4,5};
struct check *p = (struct check *)v;

printf("%d",p->a);
printf("\t%d",p->b);

The answer is 513 and 1027. I am not able to get why it is happening. Can anybody help me on understanding the concept.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Rakesh_Kumar
  • 1,442
  • 1
  • 14
  • 30

2 Answers2

5

It's not a good idea to cast pointers like this.

Probably, unsigned short is 2 bytes on your machine, and after the cast, p->a gets the value 0x0201, which is decimal 513, and p->b gets the value of 0x0403, which is decimal 1027.

Note that the result will be different on a machine with different endianess. For example, on my machine, the output is 258 (0x0102) and 772 (0x0304).

Also note that you should use format specifier %u to print values of unsigned type:

printf("%u\t%u\n", p->a, p->b);
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
3

Updated

Here's what appears to be happening... The array of characters is laid out in memory as follows:

v+0: 0x01
v+1: 0x02
v+2: 0x03
v+3: 0x04
v+4: 0x05

When you cast v to be of type struct check * and dereference it, this region of memory is being reinterpreted as follows:

p->a: 0x0201 (v+1, v+0)
p->b: 0x0403 (v+3, v+2)

0x0201 in hexadecimal is equal to 513, and 0x0403 is equal to 1027.

Additional thoughts...

It's important to note that you can't guarantee anything about the behavior of your code. For starters, dereferencing p is a strict aliasing violation. See What is the strict aliasing rule? for an explanation of the strict aliasing rule as well as a list of other factors that affect this type of code.

Community
  • 1
  • 1
godel9
  • 7,340
  • 1
  • 33
  • 53
  • 1
    Realistically you can't guarantee anything about the behavior of this code as dereferencing p constitutes a strict aliasing violation. – tab Oct 25 '13 at 16:45
  • @tab Thanks... I've updated my answer to reflect your comment. – godel9 Oct 26 '13 at 01:40