即使编译时,以下程序编译并运行正常-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编译这段代码.
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系统上获取原型的可移植方式,那将是很棒的.