difference between and

2019-01-13 15:08发布

问题:

When I use malloc in a C program, I get a warning:

warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]

I can then include <malloc.h> or <stdlib.h> to get rid of the warning although it works without it as well.

So I was wondering, what's the difference between these headers and which one does gcc links when I don't include anything?

(I'm using ubuntu 12.04 64-bit with gcc 4.6.3)

回答1:

The <malloc.h> header is deprecated (and quite Linux specific, on which it defines non-standard functions like mallinfo(3)). Use <stdlib.h> instead if you simply need malloc(3) and related standard functions (e.g. free, calloc, realloc ....). Notice that <stdlib.h> is defined by C89 (and later) standards, but not <malloc.h>

Look into /usr/include/malloc.h you'll find there some non-standard functions (e.g. malloc_stats(3), etc...) - in addition of malloc....

And gcc don't link header files, but libraries. Read Levine's book about linkers & loaders for more.

If you don't include any headers (and dont explicitly declare malloc yourself, which would be a bad idea), malloc is implicitly declared as returning some int value (which is wrong). I do invite you to pass at least the -Wall flag to gcc when using it.

You might also pass -v to gcc to understand the actual programs involved: cc1 is the compiler proper (producing assembly code), as the assembler, ld the linker, and collect2 an internal utility which invokes the linker.



回答2:

stdlib.h is a standard C header that declares among other things the malloc(), calloc(), free() functions. This is the header you should include.

malloc.h is a non-standard header, found on many systems where it often defines additional functions specific to the malloc implementation used by that platform.

If you do not include any of these, there's no default, however if you call malloc() without a prior declaration of the malloc function, C will assume the function prototype is int malloc(); , which is often wrong. In addition to the headers, C compilers typically link to a standard library, e.g. glibc on Linux, where the implementation of malloc resides.

Note that there's a difference between header files and libraries. Header files declares things, like structs and function prototypes. Libraries contains the implementation, the compiled code. You link to library, and you #include header files.



回答3:

The headers declare different sets of functions, but both forward-declare malloc.

If you don't include either of them then you don't have a prototype for malloc, hence the warning. But you link against the same function regardless, because there is only one malloc function. It's just forward-declared in two places. The forward-declarations aren't there to help link against the malloc function, they're there so that the compiler can emit the correct code around the call, to specify the arguments and read the return value.

Note that <malloc.h> is not a standard include. I don't think stdlib.h ever includes malloc.h on GCC, but you can imagine that it might since that's one way to provide the necessary declaration.



回答4:

<malloc.h> is not a standard header and is thus not portable. The standard puts malloc() et al. in <stdlib.h>.



回答5:

Others have already discussed the differences between <malloc.h> and <stdlib.h>

As for the warning when neither is included, that is the definition of how C functions work. A function without a prototype (which is what you have when you don't declare your own and don't include a header with one) is treated as a function with an int return type and an unspecified argument list.

The compiler will perform default promotions (e.g. float to double and others) and the function is called. If the number of arguments used by the function is different from the number passed, or if the argument types after default promotions are not compatible with the function's implementation, it is undefined behavior.

See ISO 9899:1999 (C99) §6.5.2.2, ¶ 6:

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined. If the function is defined with a type that includes a prototype, and either the prototype ends with an ellipsis (, ...) or the types of the arguments after promotion are not compatible with the types of the parameters, the behavior is undefined. If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, except for the following cases:

  • one promoted type is a signed integer type, the other promoted type is the corresponding unsigned integer type, and the value is representable in both types;
  • both types are pointers to qualified or unqualified versions of a character type or void.

In the case of calling malloc() without a prototype, this has the potential to be very bad. malloc() accepts a size_t argument and returns a void * pointer. If the result of default promotion of your integer argument produces an integer different in size from size_t, you will have undefined behavior. And if int is a different size from void * (e.g. on 64-bit systems, where int is often 32-bits and void * will be 64-bits,) the returned pointer will be messed up.



回答6:

To learn the difference, you should read their contents for yourself.

By default, gcc reads neither.

When you read them, you will see that they declare malloc differently.



标签: c gcc malloc