为什么gcc不会抱怨htons()但是在使用-std = c99编译时抱怨getaddrinfo()?

Lon*_*ner 2 c posix c99

即使编译时,以下程序编译并运行正常-std=c99.

#include <stdio.h>
#include <arpa/inet.h>

int main()
{
    printf("%d\n", htons(1));
}
Run Code Online (Sandbox Code Playgroud)

这是输出.

$ gcc -std=c99 foo.c && ./a.out
256
Run Code Online (Sandbox Code Playgroud)

但是以下程序会导致警告和错误.

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

int main()
{
    struct addrinfo *res;
    getaddrinfo("localhost", NULL, NULL, &res);
    printf("%d\n", res->ai_flags);
}
Run Code Online (Sandbox Code Playgroud)

这是警告和错误.

$ gcc -std=c99 bar.c
bar.c: In function ‘main’:
bar.c:9:5: warning: implicit declaration of function ‘getaddrinfo’ [-Wimplicit-function-declaration]
     getaddrinfo("localhost", NULL, NULL, &res);
     ^
bar.c:10:23: error: dereferencing pointer to incomplete type
     printf("%d\n", res->ai_flags);
Run Code Online (Sandbox Code Playgroud)

为什么编译器不会抱怨htons()但是getaddrinfo()在编译时会抱怨-std=c99

我正在使用Debian 8.3系统上的gcc 4.9.2编译这段代码.

Kla*_*äck 5

来自glibc的Linux 手册页:

POSIX.1-2001. htons()

POSIX.1-2001,POSIX.1-2008.RFC 2553中记录了getaddrinfo()函数.

由于glibc 2.22:_POSIX_C_SOURCE> = 201112L

Glibc 2.21及更早版本:_POSIX_C_SOURCE

要获取原型,getaddrinfo()需要在包含标题之前指定要使用的POSIX版本,例如:

#define _POSIX_C_SOURCE 201112L
Run Code Online (Sandbox Code Playgroud)

RFC 2553为套接字接口添加了IPv6支持.添加意味着添加了新的结构.由于并非所有的plkatforms都能立即实现新的东西,因此需要指定更改内容所需的接口版本.htons在所有版本中都是相同的,因此它不关心您请求的版本.getaddrinfo由于RFC 2553而发生了变化,因此您需要指定您希望/(可以处理)更改后的版本.

如评论中所述,_POSIX_C_SOURCE所需的值因平台而异.似乎对于RHEL6上的gcc,指定_POSIX_SOURCE或_POSIX_C_SOURCE> = 1就足够了.

如果有人能够确认_POSIX_SOURCE是否是getaddrinfo在任何POSIX系统上获取原型的可移植方式,那将是很棒的.