简体   繁体   中英

Conflicting Man pages on a struct in C

I am trying to use the function .net_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 .net.net/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?

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); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM