我正在阅读 getaddrinfo 的手册页并尝试按照示例代码进行操作,但无法编译:
// test.c
#include <netdb.h>
void f() {
struct addrinfo t;
}
两者都带有 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.
和 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;
^
经过一番挖掘,我发现 glibc headers有一个预处理器指令来“保护”(这是正确的术语吗?)
struct
从被定义,所以我想知道:#ifdef __USE_XOPEN2K
和 others don't ?有什么用?为什么从 __USE_POSIX 变了? __USE_XOPEN2K
与 -std=gnu89
, -std=gnu90
, -std=gnu99
但不是 -ansi
, -std=c89
, -std=c90
, -std=c99
和 -std=c11
? -std=gnuXX
或使用 #define __USE_XOPEN2K
? 最佳答案
简短的回答,如果您将 glibc 与不属于标准 C(任何与 UNIX 相关的)的 API 一起使用,只需使用 -std=gnuXX
— 这将启用 couple of features in the glibc . docs
长答案:
这是一个复杂的问题,C 编程语言和 Unix 操作系统都是旧的,有很多包袱;这是我试图理解所有这些的尝试。
有一种 C 编程语言。该语言出现于 1972 年,但直到 1989 年第一个 ANSI C 被批准时才标准化。目前有这些 C 编程语言的规范:
C 标准有一个真正的 limited scope ,它提供了语法、语义和 some library headers and functions .规范( c99 和 c11 )包含一些编译器应该公开的预定义宏,这些宏用于表明符合标准,以便程序可以使用旧规范没有的新功能,但是有不是源代码可以用来删除功能的宏。
除了 C 编程语言规范,还有几个 UNIX specifications .尝试制作 long story和错综复杂的历史,忽略商标和法律术语的问题:
UNIX 开始时没有规范,其源代码被非法复制和修改,结果是 long list UNIX 变体,其中一些发明了不兼容或冲突的 API,例如 BSD 的 tty 套接字和 SVR3 termio。一段时间后,成立了工作组来标准化操作系统:
这些小组的工作可以用这个不完整的时间表来描述:
[IEEE 标准 1003.1-2004]
缩写词是:
好的,现在 GCC 和 glibc 需要编译和链接到任何使用这些标准开发的 C 程序,glibc docs说:
If you compile your programs using ‘
gcc -ansi
’, you get only the ISO C library features, unless you explicitly request additional features by defining one or more of the feature macros [...]. You should define these macros by using ‘#define
’ preprocessor directives at the top of your source code files. These directives must come before any #include of a system header file [...]. This system exists to allow the library to conform to multiple standards.
GCC 关于 language's dialects 的文档声明如下:
-ansi
is equivalent to-std=c90
[...]. This turns off certain features of GCC that are incompatible 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’
is the same as-ansi
for C code.
还有关于 standard libraries 的文档:
If you need a standard-compliant library, then you need to find one, as GCC does not provide one. The GNU C library (called glibc) provides ISO C, POSIX, BSD, SystemV and X/Open compatibility for GNU/Linux and HURD-based GNU systems;
有用的链接:
关于c - 为什么 struct addrinfo 仅在定义了 __USE_XOPEN2K 时才定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33076175/