我真的需要头文件来使用库吗?我的代码在没有头文件的情况下工作,并且库完美链接,除了我收到“警告:函数的隐式声明”消息。仍然只是我的程序运行的警告。
4 回答
我的代码在没有头文件的情况下工作,并且库完美链接,除了我收到“警告:函数的隐式声明”消息。仍然只是我的程序运行的警告。
忽略来自编译器的警告是一种不好的做法。未正确编译的程序可能会出现错误,这些错误可能会在将来给您带来更大的问题和错误。
例如,如果您收到警告:
prog.c:12:5: warning: implicit declaration of /*some function used in the program*/
预计您必须包含定义该函数的头文件。
对于大多数初学者来说,当他们开始使用时会看到这个警告
malloc
所以我正在使用这个例子。对于这种情况下的警告,您需要添加:
#include <stdlib.h>
该文件包括内置函数的声明malloc
。如果你不这样做,编译器会认为你想定义你自己的命名函数malloc
,它会警告你,因为:
- 您没有明确声明它并且
- 已经有一个同名的内置函数,其签名与隐式声明的签名不同(当隐式声明函数时,假定其返回和参数类型为
int
,这与内置函数不兼容inmalloc
,它接受 asize_t
并返回 avoid*
)。
我真的需要头文件来使用库吗?
是的。
我的代码在没有头文件的情况下工作
不,它没有。它似乎只是在工作。
并且库完美链接,除了我收到“警告:函数的隐式声明”消息
在这种情况下,我不会称其为“完美”。
仍然只是我的程序运行的警告。
而且你永远不知道它做了什么,因为它现在调用了未定义的行为。“只是一个警告”?当然。编译器警告您是有原因的。尊重警告并修复它们。
这是来自 C99 (6.5.2.2.6) 的引用,它解释了为什么程序有没有标题的 UB(更准确地说,没有你似乎没有的适当的函数原型):
- 如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,而浮点类型的参数将提升为双精度。这些称为默认参数提升。如果参数的数量不等于参数的数量,则行为未定义。
如果函数使用包含原型的类型定义,并且原型以省略号 (, ...) 结尾,或者提升后的参数类型与参数类型不兼容,则行为未定义。
如果函数定义的类型不包含原型,并且提升后的参数类型与提升后的参数类型不兼容,则行为未定义,但以下情况除外:
— 一种提升类型是有符号整数类型,另一种提升类型是对应的无符号整数类型,并且值可以在两种类型中表示;
— 两种类型都是指向字符类型或 void 的限定或非限定版本的指针。
使用头文件是有充分理由的。发明和设计该语言的人知道他们在做什么,他们做出这个决定是因为它是必要的,也是解决类型需要在编译单元中可见的问题的一个很好的解决方案。