Why is struct addrinfo defined only when __USE_XOPEN2K is defined?

I am reading the getaddrinfo man page and trying to follow the code example, but it does not compile:

// test.c #include <netdb.h> void f() { struct addrinfo t; } 

Both with clang:

 $ clang -std=c11 test.c test.c:10:21: error: variable has incomplete type 'struct addrinfo' struct addrinfo t; ^ test.c:10:12: note: forward declaration of 'struct addrinfo' struct addrinfo t; ^ 1 error generated. 

and gcc:

 $ gcc -std=c11 test.c test.c: In function 'f': test.c:10:21: error: storage size of 't' isn't known struct addrinfo t; ^ 

After some digging, I found that glibc headers have a preprocessor directive that β€œprotects” (is this the correct term?) struct from being defined, so I wonder:

  • Why #ifdef __USE_XOPEN2K glibc use #ifdef __USE_XOPEN2K and others not ? what is it used for? why has it changed from __ USE_POSIX ?
  • Why does clang and gcc define __USE_XOPEN2K with -std=gnu89 , -std=gnu90 , -std=gnu99 , but not with -ansi , -std=c89 , -std=c90 , -std=c99 and -std=c11 ?
  • What should I use to not get an error? Use -std=gnuXX or use #define __USE_XOPEN2K ?
+5
source share
1 answer

The short answer is, if you use glibc with APIs that are not part of standard C (something related to UNIX), just use -std=gnuXX - this will allow several functions in glibc . docs


Long answer:

This is a difficult question; the C programming language and Unix OS are old and have a lot of luggage; it is my attempt to understand all this.

There is a programming language C. The language appeared in 1972, but it was not standardized until 1989, when the first ANSI C was ratified. Currently, these specifications of the C programming language:

  • 1989 Known as ANSI C or C89 [X3.159-1989].
  • 1990 Known as ISO C or C90 [ISO / IEC 9899: 1990]
  • 1995 Known as AMD1 or C94 or C95 [ISO / IEC 9899: 1990 / AMD 1: 1995]
  • 1999 Known as C99 [ISO / IEC 9899: 1999]
  • 2011 Known as C11 or C1X [ISO / IEC 9899: 2011]

The C standard has a really limited scope ; it provides syntax, semantics, and some library headers and functions . The specifications ( c99 and c11 ) contain some predefined macros that the compiler must provide, these macros are used to indicate compliance with the standard, so that the program can use new functions that were not installed by older specifications, but a macro that the source code could not use to remove functions.

Besides the C programming language specification, there is a couple of UNIX specifications . Trying to make a long story and shortest story short, ignoring trademark and legalization issues:

At the beginning, UNIX did not have a specification, and the source was kind of illegally copied and modified, the result is a long list of UNIX variants, some of which came up with incompatible or inconsistent APIs such as the BSD tty socket and termio SVR3. After some time, working groups were created to standardize the OS:

  • 1983 Uniforum also knows that / usr / group created the first standardization called the UNIX base system
  • 1985 . AT & T had a V-interface or SVID interface definition
  • 1984 The Open Group also knows that X / Open created the X / Open or XPG Portability Guide,
  • 1985 The IEEE 1003 group is created, they created the POSIX standard

The work of these groups can be described with this incomplete timeline:

  • 1983 Uniforum created the base UNIX system or UDS 83 [Uniforum 1983 Draft Standard]
  • 1985 SVID replaced UDS 83
  • 1985 XPG1 with APIs from SVR2 and 4.2BSD (POSIX plus sockets)
  • 1987,1990,1992 XPG2, XPG3 and XPG4
  • 1988 - 1995 The first documents that make up the POSIX standard (1003.1, 1003.2 * and 1003.4)
  • 1997 SUSv2
  • 2004 POSIX: 2004 or SUSv3 , updated version of 2001 [IEEE Std 1003.1-2004]
  • 2008 POSIX: 2008 [IEEE Std 1003.1-2008]

Acronym:

  • SUS refers to the Unix Unified Specification
  • XPG refers to X / Open Portability Guides
  • POSIX refers to the portable operating system interface

So now GCC and glibc need to be compiled and linked to any C program designed with any of these standards in mind, glibc docs says:

If you compile your programs using ' gcc -ansi , you only get the functions of the ISO C library, unless you explicitly request additional functions by defining one or more function macros [...]. You must define these macros using the #define preprocessor directives at the top of the source files. These directives must be present before any #include system header file [...]. This system exists so that the library meets several standards.

GCC language dialect documents state the following:

-ansi equivalent to -std=c90 [...]. This disables some GCC features that are not compatible with ISO C90 (when compiling C code), such as the asm and typeof keywords, and predefined macros, such as unix and vax, that identify the type of system you are using. -std='c89' same as -ansi for C code.

Also documents about standard libraries :

If you need a standard library, then you need to find it, because GCC does not provide it. The GNU C library (called glibc) provides compatibility with ISO C, POSIX, BSD, SystemV and X / Open for GNU systems GNU / Linux and HURD;

Useful links:

+2
source

Source: https://habr.com/ru/post/1233505/


All Articles