I learn now about sockets and I find it very confusing because the casting structres.
The guide say to include 8 bit inside the sockaddr_in to compare it to sockaddr.
So my question is why to do it I mean when you cast you dont compare the char size to int
For example you do
char a[1]='1';
int b=(int)a;
and not
char a[2]='1';//compare to size of int
int b=(int)a;
so how is it working?
Is it diiferent when its castig strucres?
If yes so why?
When passing pointers to structures, the function that receives it may try to access any of all its fields.
If you receive a
struct something *, you expect that you can read any of thesizeof(struct something)bytes following the pointer you receive. So, not reserving those bytes in your ownstructwould make them incompatible – whenever the function tries to access the bytes you haven’t allocated, it would be accessing non-reserved memory, so it can be a segmentation fault, or can corrupt another’s structure data.Look at this program:
And a sample output:
What we’ve learnt here is that each field is stored next to the previous one in memory, more precisely
sizeof(previous_field)bytes to the right of the previous field (whenstructispacked– see this for understanding why packed, but this is the ideal case).So, imagine we would like to create another
structto be compatible with this one. If we create something like:We can pass a
struct small_pair *to any function that expects astruct pair *by casting:Once compiled, accessing
a_pair->secondis “read the one byte which is two bytes after the start of the struct” (0xabbd0aa2 - 0xabbd0aa0 = 2). So that would be the third byte of the fieldfirstof astruct small_pair, whichever value it has.But, what about
a_pair->last? It’s0xf(15) bytes after the struct’s start, but it’s clearly out of it’s space (sizeof(struct small_pair)is just 14).So it will depend on the way variables got loaded in memory, but clearly we will not be referring to the value we wanted. The best case would be when that address is out of our process space, so we get a Segmentation Fault, and the program aborts. But it could well be that there’s another variable declared in that position of memory, and we will be reading/writing a different variable from what we wanted, leaving to who-knows-what results.
So, if we just add another 2-bytes-long field to the end of the
struct small_pair, we guarantee that every possible reference of astruct pairwill still be correct in our ownstruct, so they’ll be compatible at memory-level.Then, it’s still left the semantic-level compatibility, but that’s a different story 🙂