2

I get the following errors when I try to compile my code:

main.c:13:40: note: each undeclared identifier is reported only once for each function it appears in
main.c:17:14: error: ‘EAI_ADDRFAMILY’ undeclared (first use in this function); did you mean ‘EAI_FAMILY’?
         case EAI_ADDRFAMILY:
              ^~~~~~~~~~~~~~
              EAI_FAMILY
main.c:29:14: error: ‘EAI_NODATA’ undeclared (first use in this function); did you mean ‘EAI_NONAME’?
         case EAI_NODATA:
              ^~~~~~~~~~
              EAI_NONAME

I've tried including different headers (e.g. netinet/in.h) as well as compiling with different standards (gnu90, gnu99, gnu11), but nothing seems to resolve the error.

The following is my code:

// Name: main.c
// Compile: gcc -std=gnu11 main.c
// Error:
//   main.c: In function ‘main’:
//   main.c:18:14: error: ‘EAI_ADDRFAMILY’ undeclared (first use in this function); did you mean ‘EAI_FAMILY’?
//            case EAI_ADDRFAMILY:
//                 ^~~~~~~~~~~~~~
//                 EAI_FAMILY
//   main.c:18:14: note: each undeclared identifier is reported only once for each function it appears in
//   main.c:30:14: error: ‘EAI_NODATA’ undeclared (first use in this function); did you mean ‘EAI_NONAME’?
//            case EAI_NODATA:
//                 ^~~~~~~~~~
//                 EAI_NONAME

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

int main()
{
    struct addrinfo* res;
    char* domain = "google.com";

    switch(getaddrinfo(domain, "http", NULL, &res))
    {
        case 0:
            break;
        case EAI_ADDRFAMILY:
            break;
        case EAI_AGAIN:
            break;
        case EAI_BADFLAGS:
            break;
        case EAI_FAIL:
            break;
        case EAI_FAMILY:
            break;
        case EAI_MEMORY:
            break;
        case EAI_NODATA:
            break;
        case EAI_NONAME:
            break;
        case EAI_SERVICE:
            break;
        case EAI_SOCKTYPE:
            break;
    }

    return 0;
}
adyavanapalli
  • 490
  • 6
  • 17
  • 1
    Okay i searched a bit around and indeed the man pages state that the above mentioned defines should be in `netdb.h`. However they are not at least for the header on my system and the header of [the open group](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html) and appearently yours too. They are however defined in `addrinfo.h` but that will give conflicts about multiple definition. Thats what bothers me sometimes the man pages are just a confusing mess – Yastanub Jun 05 '19 at 11:32
  • Hmm, when I examine `netdb.h` on my system, it does seem to be in there but only when `__USE_GNU` is defined. I'll have to see how that flag is enabled. – adyavanapalli Jun 05 '19 at 12:10
  • As an addition you could use `gai_strerror()` to convert any returned result into a readable string for error output. This however means you can not react to an error but just message and exit. – Yastanub Jun 05 '19 at 12:10
  • see [this answer](https://stackoverflow.com/a/7297011/9232218) for enabling __USE_GNU yourself – Yastanub Jun 05 '19 at 12:12
  • @Yastanub I'm a little bit weary about defining `_GNU_SOURCE` myself. Do you know whether this definition is _supposed_ to be user defined, or is is enabled by use of some compiler flag? – adyavanapalli Jun 05 '19 at 12:15
  • 1
    [Take a look here](https://stackoverflow.com/a/5583764/9232218) I somethimes find it very difficult to work with posix functions since the documentaries are sometimes so ambigous and i have never before used `_GNU_SOURCE` myself before. – Yastanub Jun 05 '19 at 12:18
  • @Yastanub, Sounds good. Thanks for your help! – adyavanapalli Jun 05 '19 at 12:25
  • If you don't want to define `_GNU_SOURCE`, does `-D_XOPEN_SOURCE=600` or `-D_POSIX_C_SOURCE=200112L` work? – Ian Abbott Jun 05 '19 at 12:29
  • @IanAbbott No, neither of those flags work. – adyavanapalli Jun 05 '19 at 12:33
  • Oh I see it's just the GNU-specific `EAI_` macros you are having trouble with. Defining `_POSIX_C_SOURCE` to be >= `200112L` only defines the POSIX standard `EAI_` macros. – Ian Abbott Jun 05 '19 at 14:44

1 Answers1

3

It turned out that although the two definitions, EAI_ADDRFAMILY and EAI_NODATA, were defined in netdb.h on my system, they were not enabled because it required that __USE_GNU be defined.

To enable __USE_GNU (indirectly), we define _GNU_SOURCE at the top of the file. The working file is the following:

// Name: main.c
// Compile: gcc -std=gnu11 main.c

#define _GNU_SOURCE // Need for EAI_ADDRFAMILY and EAI_NODATA

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

int main()
{
    struct addrinfo* res;
    char* domain = "google.com";

    switch(getaddrinfo(domain, "http", NULL, &res))
    {
        case 0:
            break;
        case EAI_ADDRFAMILY:
            break;
        case EAI_AGAIN:
            break;
        case EAI_BADFLAGS:
            break;
        case EAI_FAIL:
            break;
        case EAI_FAMILY:
            break;
        case EAI_MEMORY:
            break;
        case EAI_NODATA:
            break;
        case EAI_NONAME:
            break;
        case EAI_SERVICE:
            break;
        case EAI_SOCKTYPE:
            break;
    }

    return 0;
}
adyavanapalli
  • 490
  • 6
  • 17
  • 1
    But note that there may be a reason these codes where excluded from posix as described [here](https://stackoverflow.com/questions/5582211/what-does-define-gnu-source-imply/5583764#5583764) – Yastanub Jun 05 '19 at 12:47