Is invalid for one.
connect(sockfd, struct sockaddr *dest_addr, sizeof dest_addr)
As you know, pointers hold addresses to certain things (they have a type so you know what they point to),
ie: char * test;
test is a pointer to a character (it holds the address of a character).
connect() expects the address of a struct sockaddr, since sockaddr and sockaddr_in are the same in size, and it's perfectly fine to cast one to the other you can do so.
&dest_addr will give you the address of dest_addr, you then use must cast this address to a struct sockaddr * (pointer) as connect() expects.
It's the same as writing:
Basically, a simplified version:
struct sockaddr_in dest_addr;
struct sockaddr_in * pointerToDestAddr = &dest_addr; /* a pointer to dest_addr of type sockaddr_in */
/* cast the pointer to sockaddr, so the compiler knows what you're pointing to */
connect(sockfd, (struct sockaddr *)pointerToDestAddr, sizeof dest_addr);
You can see foo() expects a pointer to a struct b_s, but you have a struct a_s -- thus you must cast the pointer or the object.
void foo(struct b_s * blah)
struct a_s dest_addr;
struct b_s tmp;
foo(&dest_addr); /* This is illegal, incompatible pointer types -- a_s is different from b_s as expected by foo() */
/* legal */
foo((struct b_s *) &dest_addr);
/* also legal (essentially the same thing) */
tmp = (struct b_s) dest_addr;
Be careful, this doesn't work all the time (in this example it does, sizeof(struct a_s) == sizeof(struct b_s)) and they both have the same type & # of elements.
I hope I cleared it up.