Have you considered endianness?
EDIT: Now to add more clarity ...
As others have mentioned in the comments, this is most definitely undefined behavior! This is not just "not good practice", it's just don't do it!
Pointers on C is an excellent book that goes over everything you wanted to know about pointers and more. It's dated but still very relevant. You can probably find most of the information online, but I haven't seen many books that deal with pointers as completely as this one.
Though it sounds like you are experimenting, possibly as part of a class. So, here are a number of things wrong with this code:
- endianness
- memory access model
- assumption of type size
- assumption of hardware architecture
- cross type casting
Remember, even though C is considered a pretty low level language today, it is still a high level programming language that affords many key abstractions.
Now, look at your declaration again.
int arr[5];
You've allocated 5 ints grouped together and accessed via a common variable named arr. By the standard, the array is 5 elements of at least 2 bytes per element with base address of &arr[0]
. So, you aren't guaranteed that an int is 2 bytes, or 4 bytes or whatever. Likewise, as short is defined by the standard as at least 2 bytes. However, a short is not an int even if they have the same byte width! Remember, C is strongly typed.
Now, it looks like you are running on a machine where shorts are 2 bytes and ints are 4 bytes. That is where the endianness issue come into play: where is your most significant bit? And where is your most significant byte?
By casting the address of arr to a short pointer first of all breaks both the type and the memory access model. Then, you want to access the 6th element from the offset of arr. However, you aren't accessing relative to the int you declared arr to be, you are accessing through a short pointer that is pointing at the same address as arr!
These following operations ARE NOT the same! And it also falls into the category of undefined - don't do this ever!
int foo;
int pfooInt;
short bar;
short * pfooShort;
bar = (short) foo;
pfooShort = (short*)&foo;
pfooInt = &foo;
bar = *pfooShort;
pfooShort = (short*)pfooInt[0];
Another thing to clarify for you:
int arr[5];
((short *)arr)[6] ...
This does not transform your int array of 5 elements into a short array with 10 elements. arr is still an int array of 5 elements. You just broke the access method and are trying to modify memory in an undefined manner. What you did is tell the compiler "ignore what I told you about arr previously, treat arr as a short pointer for the life of this statement and access/modify 6th short relative to this pointer."