当我在C程序中使用malloc
时,我会得到警告:
warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]
i然后可以包括<malloc.h>
或<stdlib.h>
,以摆脱warning
,尽管它也没有它。
所以我想知道,当我不包含任何内容时,这些标头和哪一个链接有什么区别?
(我将ubuntu 12.04 64-bit
与gcc 4.6.3
一起使用)
<malloc.h>
标头已弃用(并且是特定于linux的,它在其上定义了 non - 标准的功能,例如mallinfo(3))。如果您只需要Malloc(3)和相关的标准功能(例如free
,calloc
,realloc
....),则使用<stdlib.h>
。请注意,<stdlib.h>
由C89(及以后)标准定义,但不定义<malloc.h>
查看/usr/include/malloc.h
,您会发现一些非标准功能(例如malloc_stats(3),等等) - 除了malloc
....
和gcc
不要链接标头文件,而是库。阅读Levine的有关Linkers&amp;的书更多的装载机。
如果您不包含任何标题(并且不要明确声明malloc
自己声明,这是一个坏主意),malloc
被隐式声明为返回某些int
值(这是错误的)。我确实邀请您在使用时至少将-Wall
标志传递给gcc
。
您也可以将-v
传递给gcc
以了解所涉及的实际程序:cc1
是编译器适当的(生产汇编代码),as
CC_26汇编程序,ld
链接器,并收集了调用链接器的内部实用程序。
stdlib.h 是标准C标头,声明malloc()
,calloc()
,free()
功能。这是您应该包括的标题。
malloc.h 是一个非标准标头,在许多系统中发现了通常定义该平台使用的Malloc实现的其他功能。
如果您不包括其中任何一个,则没有默认值,但是,如果您在没有事先声明malloc函数的情况下调用malloc()
,则C将假定函数原型为int malloc();
,通常是错误的。除标题外,C编译器通常链接到标准库,例如在Linux上的GLIBC,MALLOC的实现位于其中。
请注意,标题文件和库之间存在差异。标头文件声明内容,例如结构和功能原型。库包含实现,即编译的代码。您链接到库,然后您的#include
标头文件。
标题声明了不同的函数集,但均指向forward-declare malloc
。
如果您不包括其中任何一个,则没有malloc
的原型,因此警告。但是,无论如何,您都可以链接到相同功能,因为只有一个malloc
功能。它只是在两个地方向前宣布。前截面不足以帮助针对malloc
函数链接,它们在那里,以便编译器可以在呼叫周围发射正确的代码,以指定参数并读取返回值。
请注意,<malloc.h>
不是标准。我认为stdlib.h
从未在GCC上包含malloc.h
,但是您可以想象这可能是提供必要声明的一种方法。
<malloc.h>
是不是标准标头,因此无法便携。标准将malloc()
等。在<stdlib.h>
。
其他人已经讨论了&lt; malloc.h&gt;and&lt; stdlib.h&gt;
对于不包括在内的警告,这是C函数工作方式的定义。没有原型的功能(这是您不声明自己的声明而不包含一个标头时拥有的功能)被视为具有int
返回类型和 nOm>未指定的参数的函数列表。
编译器将执行默认的促销(例如浮动到double和其他),并调用该功能。如果函数使用的参数数与传递的数字不同,或者默认促销后的参数类型与函数的实现不兼容,则是未定义的行为。
参见ISO 9899:1999(C99)§6.5.2.2,¶6:
如果表示调用函数的表达式具有不包含原型的类型,则在每个参数上执行整数促销,并且具有
:float
类型的参数被提升为double
。这些被称为默认参数促销。如果参数数量不等于参数的数量,则行为是未定义的。如果该函数用包含原型的类型定义,并且原型以椭圆(,...)结束,或者促销后的参数类型与参数类型不兼容,则行为是未定义的。如果该函数使用不包含原型的类型定义,并且促销后参数的类型与促进后参数的参数类型不兼容,则行为是不确定的,除了以下情况:
- 一种晋升类型是签名的整数类型,另一个晋升类型是相应的无符号整数类型,并且该值在两种类型中均可表示;
- 两种类型都是字符类型或
void
的合格或不合格版本的指针。
在没有原型的情况下调用malloc()
,这有可能非常糟糕。malloc()
接受gcc
0参数并返回void *
指针。如果您的整数参数的默认促销结果产生的整数与size_t
不同,则您的行为将不确定。如果int
与void *
的大小不同(例如,在64位系统上,int
通常是32位,而void *
将是64位,则将返回的指针被弄乱。
要学习差异,您应该自己阅读其内容。
默认情况下,GCC都没有读取。
当您阅读它们时,您会发现它们以不同的方式声明malloc
。