Thread: Casting and Pointers

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    67

    Casting and Pointers

    One of the more difficult concepts to grasp, for me, are pointers and type casting. For instance, I don't know WHY it's possible to cast struct sockaddr_in to struct sockaddr when working with winsock, other than because I'm told I have to.

    If possible, can someone break down the next few lines of code to me in lamemen's (sp?) terms for me? I'll attempt to, but I'll no doubt be way off...


    hostent* localHost; //LINE 1
    char* localIP; //LINE 2
    localHost = gethostbyname(""); //LINE 3
    localIP = inet_ntoa (*(struct in_addr *)*localHost->h_addr_list); //LINE 4

    LINE 1: declares a null pointer of type hostent
    LINE 2: delcares a null pointer of type char
    LINE 3: localHost now points to an address in memory... somewhere.
    LINE 4: Totally lost. Dereferencing localHost.h_addr_list[0], casting it to struct in_addr *, then dereferencing that again? Why not (struct in_addr)*localHost->h_addr_list other than because it won't work?

  2. #2
    * noops's Avatar
    Join Date
    Jun 2008
    Posts
    108
    What is h_addr_list?

    The only time I've done something like this in my short history with C is when I used void pointers like:
    Code:
    int n = 8;
    void* data = &n;
    void** ptr = &data;
    printf("%d", *(int *)*ptr);
    So maybe h_addr_list dereferences to a void pointer. Just my 2 cents, let's see what someone more experienced says.

    edit: the reason for the cast is because you can't (or shouldn't?) dereference a void pointer (unless it dereferences to a pointer?).
    Last edited by noops; 08-27-2008 at 03:00 PM.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Wrong. None of those point to a NULL pointer because they aren't set to NULL.

    1. Declares a pointer to a hostent type. Since it's no initialized, it points to some random garbage value.
    2. Declares a pointer to a char string. Again, pointing to garbage.
    3. Returns a pointer to a hostent type which points to a static variable (or maybe global) that is inside the gethostbyname() function.
    4. Breaking it down step by step:
    *localHost->h_addr_list
    De-references the h_addr_list member.

    *(struct in_addr *)
    Casts the first element of the h_addr_list into a in_addr pointer, then de-references it.

    localIP = inet_ntoa( ... )
    Calls the inet_ntoa() function and assigns the result to localIP.

    Why not (struct in_addr)*localHost->h_addr_list other than because it won't work?
    Because h_addr_list is a char** (i.e. a pointer to a pointer), not a char*, so you need to de-reference it twice.
    Last edited by cpjust; 08-27-2008 at 03:09 PM.

  4. #4
    Registered User
    Join Date
    Aug 2008
    Posts
    67
    Quote Originally Posted by cpjust View Post
    Wrong. None of those point to a NULL pointer because they aren't set to NULL.

    1. Declares a pointer to a hostent type. Since it's no initialized, it points to some random garbage value.
    2. Declares a pointer to a char string. Again, pointing to garbage.
    Thank you for correcting my assumtion.

    *(struct in_addr *)
    Because h_addr_list is a char** (i.e. a pointer to a pointer), not a char*, so you need to de-reference it twice.
    That was exactly the answer I was looking for. Thank you for your quick response. Would (struct in_addr)*localHost->h_addr_list be correct if it was a char *?

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by kpreston View Post
    Thank you for correcting my assumtion.



    That was exactly the answer I was looking for. Thank you for your quick response. Would (struct in_addr)*localHost->h_addr_list be correct if it was a char *?
    I think in that case you'd need to use this:
    Code:
    *(struct in_addr*)localHost->h_addr_list
    But maybe it would work the other way too, I'm not 100% sure? If it was something other than char* then you'd definitely need to cast it to a in_addr* first, and then de-reference it.

  6. #6
    Registered User
    Join Date
    Aug 2008
    Posts
    67
    Quote Originally Posted by cpjust View Post
    If it was something other than char* then you'd definitely need to cast it to a in_addr* first, and then de-reference it.
    Why?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by cpjust View Post
    But maybe it would work the other way too, I'm not 100% sure?
    I don't think it would work. Granted, I don't know C, but in C++, it would simply complain that it can't convert char to struct in_addr.
    When we dereference it, we get a single char and all other information is lost anyway, so even if it works, it would be a bad idea™.

    Quote Originally Posted by kpreston View Post
    Why?
    OK the thing here is that in C (and C++), everything stored in memory is stored in 0s and 1s. The type of the variable you use determine how that data is interpreted and used.
    That's why such a thing is possible. Also in C, because it doesn't really support things as templates, usually functions that might expect several types only takes ONE type and from certain conditions and data is determines the actual type of the data passed into it. I believe this is the case with winsock.
    So you just have to cast it to the correct type so the function can use the information correctly.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by kpreston View Post
    lamemen's (sp?) terms
    That's "layman's terms"

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by QuantumPete View Post
    That's "layman's terms"

    QuantumPete
    LOL!!

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Elysia View Post
    I don't think it would work. Granted, I don't know C, but in C++, it would simply complain that it can't convert char to struct in_addr.
    When we dereference it, we get a single char and all other information is lost anyway, so even if it works, it would be a bad idea™.
    I was thinking it needed to be cast to a pointer first because of alignment issues, but since char is 1 byte, maybe it wouldn't have the same issue as int or anything else? But either way, it's probably better to always cast to the right pointer type first, then de-reference it.

  11. #11
    Registered User
    Join Date
    Aug 2008
    Posts
    67
    Thank you all (even you, QuantumPete).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 05-21-2009, 05:47 PM
  2. simple question about pointers and casting
    By steve1_rm in forum C++ Programming
    Replies: 3
    Last Post: 03-28-2008, 02:25 PM
  3. Replies: 8
    Last Post: 01-23-2008, 04:22 AM
  4. casting to void pointers dynamically
    By dp_goose in forum C++ Programming
    Replies: 3
    Last Post: 07-19-2003, 12:46 AM
  5. Casting function pointers into char arrays and back
    By coolman0stress in forum C++ Programming
    Replies: 2
    Last Post: 07-05-2003, 01:50 PM