首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >未正确链接

未正确链接
EN

Stack Overflow用户
提问于 2011-09-27 15:41:05
回答 4查看 18.8K关注 0票数 13

我试图编译这个程序,在第19页的Beej网络编程指南中提到了这一点。

代码语言:javascript
复制
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>

int main() {
    int status;
    struct addrinfo hints;
    struct addrinfo *servinfo;          /* Will point to the results */
    memset(&hints, 0, sizeof hints);    /* Make sure the struct is empty */
    hints.ai_family = AF_UNSPEC;        /* Don't care IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }

    /* Servinfo now points to a linked list of 1 or more struct addrinfos
        ... do everything until you don't need servinfo anymore .... */

    freeaddrinfo(servinfo); /* Free the linked-list */

    return 0;
}    

在其他错误中,我看到

代码语言:javascript
复制
../main.c:8:18: error: storage size of ‘hints’ isn’t known
../main.c:13:19: error: ‘AI_PASSIVE’ undeclared (first use in this function)
../main.c:16:3: warning: implicit declaration of function ‘gai_strerror’

看来gcc并没有和netdb.h建立联系。Eclipse是我用来构建这个文件的IDE,它可以很好地找到文件。下面是编译器命令:

代码语言:javascript
复制
gcc -O0 -g3 -pedantic -Wall -c -fmessage-length=0 -ansi -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.c"

添加-lnetdb不能解决这个问题。还有..。

代码语言:javascript
复制
~> find /usr/include/ -name netdb.h
/usr/include/bits/netdb.h
/usr/include/gssrpc/netdb.h
/usr/include/netdb.h
/usr/include/rpc/netdb.h

我认为这些文件是预装在我的openSUSE主机上的。gcc为什么不检测netdb.h?还是我得出了错误的结论?

EN

Stack Overflow用户

回答已采纳

发布于 2011-09-27 17:26:58

./main.c:8:18:错误:“提示”的存储大小未知./main.c:13:19:错误:‘AI_PASSIVE’未声明(在此函数中首次使用)./main.c:16:3:警告:函数‘gai_strerror’的隐式声明

看来gcc和netdb.h没有联系.

这些不是链接错误,也不需要netdb共享对象文件(没有这样的缺点;netdb.h只是定义了数据结构和宏,以便在代码中使用)。

这些是编译器错误: gcc抱怨,因为您使用的是它不识别的名称(AI_PASSIVE)和结构未知的数据类型(struct addrinfo)。

您所展示的代码似乎是正确的,addrinfo是在/usr/include/netdb.h中定义的。如果像这样编译它,会发生什么情况:

代码语言:javascript
复制
gcc -c main.c

你还会有同样的行为吗?如果是这样,请查看以下内容的输出:

代码语言:javascript
复制
gcc -E main.c

这将生成代码的预处理版本,并将所有#include语句替换为它们的实际内容。如果编译器发现了其他内容,那么您应该能够通过它查看编译器是否实际获得了/usr/include/netdb.h

代码语言:javascript
复制
$ gcc -E foo.c | grep netdb.h | awk '{print $3}' | sort -u

在我的系统中产生:

代码语言:javascript
复制
"/usr/include/bits/netdb.h"
"/usr/include/netdb.h"
"/usr/include/rpc/netdb.h"

当您将-ansi添加到命令行时,您将改变gcc的行为方式,从而破坏Linux内核和许多系统头文件。addrinfonetdb.h中的定义受到如下保护:

代码语言:javascript
复制
#ifdef  __USE_POSIX
/* Structure to contain information about address of a service provider.  */
struct addrinfo
{
  int ai_flags;                 /* Input flags.  */
  int ai_family;                /* Protocol family for socket.  */
  int ai_socktype;              /* Socket type.  */
  int ai_protocol;              /* Protocol for socket.  */
  socklen_t ai_addrlen;         /* Length of socket address.  */
  struct sockaddr *ai_addr;     /* Socket address for socket.  */
  char *ai_canonname;           /* Canonical name for service location.  */
  struct addrinfo *ai_next;     /* Pointer to next in list.  */
};

// ...other stuff...
#endif

当您使用gcc标志运行-ansi时,这将取消对__USE_POSIX宏的定义,因为受此保护的内容可能并不严格符合ANSI。如果将以下内容进行比较,您可以看到两者之间的差异:

代码语言:javascript
复制
gcc -E /usr/include/netdb.h

在这方面:

代码语言:javascript
复制
gcc -E -ansi /usr/include/netdb.h

只有前者包含addrinfo结构。

票数 17
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7571870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档