'Conflicting Man pages on a struct in C

I am trying to use the function inet_aton() defined as such:

inet_aton(const char *cp, struct in_addr *inp);

I don't want to explain what the function does, but I am getting conflicting Man pages about its 3rd argument "struct in_addr". struct in_addr is in the header file <netinet/in.h>, but the different Man pages define it differently.

defined in <netinet/in.h>

https://man7.org/linux/man-pages/man3/inet_aton.3.html
typedef uint32_t in_addr_t;

    struct in_addr
    {
        in_addr_t s_addr;
    };
    
https://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html

    struct in_addr 
    {
        unsigned long s_addr;
    };

The first man page says s_addr is an unsigned int, but the second man page says its an unsigned long int. Is there something I am missing here?

For reference, I am using this basic testing program:

#include <netinet/in.h> /* struct sockaddr_in                            */
#include <stdio.h>      /* printf() scanf()                              */
#include <sys/socket.h> /* socket() connect()                            */
#include <unistd.h>     /* read() write()                                */
#include <string.h>     /* bzero()                                       */
#include <arpa/inet.h>  /* inet_aton()                                   */

int main(void)
{
    int clisockfd;
    unsigned short int port_number;
    char sipad[12], string[32];
    struct sockaddr_in saddr;
    
    printf("Enter port number: ");
    scanf("%hu", &port_number);
        
    printf("Enter servers &ip: ");
    scanf("%s", sipad);
    
    clisockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(port_number);
    inet_aton(sipad, &saddr.sin_addr.s_addr); /*(unsigned long int)char[ipv4 dots]; will throw compiler warning lol, dont worry about it*/
    
    connect(clisockfd, (struct sockaddr *)&saddr, sizeof(saddr));
    
    printf("Please enter a message without whitespace: ");

    scanf("%s", string);
    
    write(clisockfd, string, strlen(string));
    bzero(string, 32);
    
    read(clisockfd, string, 31);
        
    printf("%s\n", string);
    
    return 0;
}

I am particularly hollowed by the comment next to it.

Here is the compiler warning:

c.c: In function ‘main’:
c.c:27:22: warning: passing argument 2 of ‘inet_aton’ from incompatible pointer type [-Wincompatible-pointer-types]
   27 |     inet_aton(sipad, &saddr.sin_addr.s_addr); /*(unsigned long int)char[ipv4 dots]; will throw compiler warning lol, dont worry about it*/
      |                      ^~~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      in_addr_t * {aka unsigned int *}
In file included from c.c:6:
/usr/include/arpa/inet.h:73:57: note: expected ‘struct in_addr *’ but argument is of type ‘in_addr_t *’ {aka ‘unsigned int *’}
   73 | extern int inet_aton (const char *__cp, struct in_addr *__inp) __THROW;

The program somehow works even though the item in question is not typecasted. Is it possible that the compiler is using the wrong man page for the warning?



Solution 1:[1]

The function expects the address of a struct in_addr. That's not what you're passing in. You're instead passing in the address of the single member of that struct whose type is in_addr_t.

It still "works" because the address of a struct and the address of its first member (when converted properly) are the same.

Pass in the address of the struct instead of the struct member:

inet_aton(sipad, &saddr.sin_addr); 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dbush