somethingSomething
somethingSomething

Reputation: 860

warning: passing argument 2 of ‘inet_aton’ from incompatible pointer type........ERROR

I don't know what this error means and what to do to fix it.

I've been following the Sock)et Programming Tutorials In C For Beginners | Part 2 by Eduonix on Youtube but I haven't been able to run anything from this guy, the code is from his tutorial.

If someone could help me understand what this error means and what to do to fix it?

Here is the error:

inet_aton(address, &remote_address.sin_addr.s_addr);
                   ^

[1007:1003 0:6758] 09:30:39 Wed May 29 [kristjan@Kundrum:pts/5 +1] ~/C_Programming
$ gcc http_client_tcp.c -o http_client_tcp
http_client_tcp.c: In function ‘main’:
http_client_tcp.c:24:24: warning: passing argument 2 of ‘inet_aton’ from incompatible pointer type [-Wincompatible-pointer-types]
     inet_aton(address, &remote_address.sin_addr.s_addr);
                        ^
In file included from http_client_tcp.c:8:0:
/usr/include/arpa/inet.h:73:12: note: expected ‘struct in_addr *’ but argument is of type ‘in_addr_t * {aka unsigned int *}’
 extern int inet_aton (const char *__cp, struct in_addr *__inp) __THROW;
            ^~~~~~~~~

I'm using Debian Linux 9.9 stretch and coding in Visual Studio Code but the error doesn't come in the Visual Code editor/debugger only if I compile in the shell.

Here is the code:

#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <sys/types.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <unistd.h> // for close

int main(int argc, char *argv[])
{
    char *address;
    address = argv[1];

    int client_socket;
    client_socket = socket(AF_INET, SOCK_STREAM, 0);

    // connect to an address
    struct sockaddr_in remote_address;
    remote_address.sin_family = AF_INET;
    remote_address.sin_port = htons(80);
    inet_aton(address, &remote_address.sin_addr.s_addr);

    connect(client_socket, (struct sockaddr *) &remote_address, sizeof(remote_address));

    char request[] = "GET / HTTP/1.1\r\n\r\n";
    char response[4096];

    send(client_socket, request, sizeof(request), 0);
    recv(client_socket, &response, sizeof(response), 0);

    printf("response from server: %s\n", response);
    close(client_socket);

    return 0;
}

Upvotes: 3

Views: 1755

Answers (2)

The tutorial is bad, the correct code is

inet_aton(address, &remote_address.sin_addr);

remote_address.sin_addr is of type in_addr, whose definition is

struct in_addr {
    unsigned long s_addr;
};

The &remote_address.sin_addr.s_addr and &remote_address.sin_addr will evaluate to the same address, but the former is of wrong type. The original will compile with warning in GCC with default settings, but it is a constraint violation!

As for the Visual Studio code, you should look harder, or perhaps compile with -Werror!


Time to look for better tutorials.

Upvotes: 6

Sourav Ghosh
Sourav Ghosh

Reputation: 134336

Check the types. From the man page

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

the second argument is a pointer to struct in_addr type variable.

In your code, you defined remote_address as

 struct sockaddr_in remote_address;

where struct sockaddr_in is defined as

struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // ***** this is the target
    char             sin_zero[8];  // zero this if you want to
};

So, your usage

 inet_aton(address, &remote_address.sin_addr.s_addr);

should be

inet_aton(address, &(remote_address.sin_addr)); // explicit parenthesis to clarify type

Upvotes: 3

Related Questions