'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 |
