casting between sockaddr and sockaddr_in

后端 未结 3 2072
独厮守ぢ
独厮守ぢ 2021-01-13 13:02

I came across a socket programming tutorial in which it is quoted

\"a pointer to a struct sockaddr_in can be cast to a pointer to a struct sockad

3条回答
  •  滥情空心
    2021-01-13 13:17

    They are of equal size, so no, you don't get any UB!

    Proof:

    #include 
    
    struct sockaddr {
      unsigned short sa_family; // address family, AF_xxx
      char sa_data[14]; // 14 bytes of protocol address
    };
    
    // src: http://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html
    struct in_addr {
        unsigned long s_addr;  // load with inet_aton()
    };
    
    struct sockaddr_in {
      short int sin_family; // Address family, AF_INET
      unsigned short int sin_port; // Port number
      struct in_addr sin_addr; // Internet address
      unsigned char sin_zero[8]; // Same size as struct sockaddr
    };
    
    int main (void) {
      printf("%zu\n", sizeof(unsigned short) + sizeof(char) * 14);
      printf("%zu\n", sizeof(short int) + sizeof(unsigned short int) + sizeof(struct in_addr) + sizeof(unsigned char) * 8);
      return 0;
    }
    

    Output:

    16
    16
    

    A good comment: sockaddr: 2+14=16, sockaddr_in:2+2+4+8=16 – Amer Agovic

    You may also want to take a look at this question: Why isn't sizeof for a struct equal to the sum of sizeof of each member?


    Please, check this question: Is it possible to cast struct to another?

    I am copying the answer of Benoit here too:

    This is refered as Type Punning. Here, both structures have the same size, so there is no question of struct size. Although you can cast almost anything to anything, doing it with structures is error-prone.

    and this one by Richard J. Ross III too:

    This is C's form of "inheritance" (notice the quotes). This works because C does not care about the underlying data in an address, just what you represent it as.

    The function determines what structure it actually is by using the sa_family field, and casting it into the proper sockaddr_in inside the function.

提交回复
热议问题