c - gcc 编译器不报告 inet_ntoa 错误

标签 c sockets networking

当我在没有 arpa/inet.h 包含的情况下使用 inet_ntoa 时,编译器为什么不报告错误?

我运行了这段代码:

struct sockaddr_in dest;
printf("%d\n", inet_ntoa(dest.sin_addr));

它返回一个非常大的有符号整数。 我有以下内容:

sys/types.h
sys/socket.h
netinet/in.h
netdb.h
stdio.h
errno.h
sys/time.h
stdlib.h
strings.h
string.h

gcc编译器版本:4.1.2 20080704(红帽4.1.2-55)

操作系统:Linux 系统的 ssh bash 接口(interface)

最佳答案

C90 标准不要求在使用函数之前声明或定义函数 - 主要是因为这样做会破坏大量现有的 C 代码,而该标准的主要目标之一是避免破坏大多数现有的C代码。这意味着 C90 编译器推断未声明的函数的返回类型为 int 。它指出,依赖这种隐式声明已经过时了。

C99 标准兑现了过时的 promise ,要求函数在使用前声明; C11 延续了这一要求。然而,大多数编译器仍然默认允许编译旧式代码,GCC 就是一个具体的例子。但是,在严格的 C99 合规模式下,需要这样的声明。

注意函数必须被声明;尽管非原型(prototype)声明也已经过时,但它们不一定需要给出原型(prototype)。

还要注意可变参数函数——带有省略号的函数 ...在它们的参数列表中——在 C90 中使用它们之前必须使用原型(prototype)进行声明。这意味着像 printf() 这样众所周知的样本必须用原型(prototype)声明,这可以通过 #include <stdio.h> 轻松完成(尽管该标准也允许使用其他等效机制)。

旧版本的 GCC(5.x 之前)在使用函数之前不会自动要求对其进行声明(C90 规则)。 GCC 5.x 默认使用 C11 规则,因此必须在使用函数之前声明它们。这一切都是默认的。您可以控制使用哪种 C 方言以及发出哪些警告。

我通常使用 GCC 并使用以下选项:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -Werror

其中一些选项在 GCC 4.1.2 中不可用,GCC 4.1.2 现在已经相当老了(从镜像站点之一的源代码来看是 2007 年 2 月)。例如,它不支持 -std=c11 ,但它将支持-std=c99-std=gnu99 ,您可以使用 90代替99-Wold-style-definition选项也可能不起作用。然而,您的代码可以使用的警告选项越多越好——几乎总是如此。 -Werror选项表示编译器将警告视为错误;我用它来保持代码整洁,但是当您努力保持代码整洁时,您可以选择将其关闭。

关于c - gcc 编译器不报告 inet_ntoa 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33980026/

相关文章:

networking - TCP 从已用于监听的端口打开套接字

security - 应用程序安全问题: How easy is it to fake an IP-Address?

用汇编语言编写的c调用函数

c - utf-8 编码的字符串如何使用 printf 在 C 中打印到屏幕?

c++ - 在 extern C 中使用 _attribute__ ((nothrow)) 有意义吗?

c# - tcp 监听器中的套接字异常

c - 消息 "warning: implicit declaration of function"

python - 使用 boto 从 S3 获取时 TCP 套接字未关闭

Java 消息被发送到一个关闭的套接字

networking - 如何创建具有相同内部 IP 地址的 docker 容器?