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)
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.
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 declare things, like structs and function prototypes. Libraries contain the implementation, the compiled code. You link to library, and you #include header files.
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.
<malloc.h> is not a standard header and is thus not portable. The standard puts malloc() et al. in <stdlib.h>.
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.
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.
Related
If I use printf, scanf, puts or some other function in C (not C++) and don't write an include line, can it be treated as unspecified or undefined behaviour?
As I remember, C didn't require porotope declaration at all, but it was recommended to have them to allow compiler to make type casts on calling. And prototypes for printf and other such functions are not required still, not sure about custom functions.
PS: This question relates to discussion in comments of https://codegolf.stackexchange.com/a/55989/32091.
Is it correct to drop #include in C?
No, it's not correct. Always include it if you use a stdio.h function like printf.
C has removed implicit declarations (with C99) and the includes are required. The only other alternative is to have a visible prototyped declaration for printf.
Moreover even when C had implicit declarations, implicit declarations are not OK for variable argument functions; so in C89 not adding a stdio.h include and not having a visible prototype (for printf example) is undefined behavior.
For professional development, no.
For codegolfing, it is ok.
If you don't declare a function, the compiler automatically generates one, which may or may not match its real declaration. If it doesn't, it may or may not produce segfault or a software bug. gcc also gives in this case a warning.
No and Yes
stdio.h has an explicit declaration of the functions you want to use, such things are prohibited if it was a C++ compiler (g++ for example).
Since c++ requires explicit declarations of all functions, but any proper C compiler will create an implicit declaration of those functions, compile the code into object file, and when linked with the standard library, it will find a definition of those functions that accidentally will match the implicit declaration, probably gcc will give you a warning.
So if you are writing software that you want to be maintainable and readable, that's not an option to drop it, however for fast prototyping or code challenges, this might not be that important.
Technically you can skip #include in many cases. But for some functions the compiler cannot generate correct function call without prototype. E.g. if a parameter is double and you put 0 - with prototype it will be converted and stored as double value in stack and otherwise there will be int which will produce wrong calculations.
I have a simple function in C which takes int* argument and I have the declaration of it in the header file like this:
void mapAuditFioError(int *errno);
But compiler cirbs compiling the files including this header as follows:
"warning: function declaration isn't a prototype"
and also:
"warning: passing argument 1 of 'mapAuditFioError' from incompatible pointer type"
even though am invoking it with a integer pointer itself.
Browsing for this warning always talks about functions like this : int func() which should actually be declared as int func(void). But what is the problem in my function above?
This is because errno is a reserved name in C (free-standing implementations aside), used for communicating erroneous conditions from standard library functions. As the glibc documentation says:
The names of all library types, macros, variables and functions that
come from the ISO C standard are reserved unconditionally; your
program may not redefine these names. All other library names are
reserved if your program explicitly includes the header file that
defines or declares them.
You cannot use errno as a variable name. It could be declared as a macro, and often it is.
For example on GCC and glibc on my Linux, if I include say <stdio.h> before the prototype,
void foo(int *errno);
is preprocessed into
void foo(int *(*__errno_location ()));
Now, that does compile without warnings because it is a legal construct; on your C compiler the errno behaves differently.
To fix it, call your parameter something else, such as errcode or error_number.
The C11 standard N1570 Committee Draft 7.5 on <errno.h> specifically says that
If a macro definition is suppressed in order to access an actual object, or a program
defines an identifier with the name
errno, the behavior is undefined.
Earlier I asked one question that is if the return of malloc is cast then the error which would be flagged is hidden
and I got the answer that is: In (older dialects of) C, you can call a function which hasn't been declared; that implicitly declares a function with a return type of int. So, if you were to call malloc() without including the header, you'd get code that erroneously assumed that it returned int. Without a cast, you'd get a compiler error when you tried to assign it to a pointer. With a cast, the code would compile, potentially giving obscure runtime errors and lengthy debugging sessions.
I understand that without inclusion of <stdlib.h> header file compiler implicitly declares a function with a return type of int.
But I confused in that according to malloc()'s function definition that is defined by creator, it will returns void * whenever we used it, but without <stdlib.h> it returns int. So how does its definition change, is compiler implicitly changing void * to int * type, or there is some other reason?
I know that I couldn't explain my question properly but if anybody understand, please explain me about that.
For C, all undeclared functions are implicitly declared to return int and take an unspecified number of unspecified arguments.
The problem with malloc is that an int and a void * may not be the same size, or even compatible. For example, on modern 64-bit machines pointers are 64-bit types while int is a 32-bit type, so if you don't have a proper declaration of malloc the compiler will drop the high 32 bits of the pointer.
In standard C, this will never happen. If you forget to include <stdlib.h> on a standard compiler and then call malloc, you will get a compiler error "implicit declaration" or similar, because the function has no prototype.
In older, obsolete versions of the C standard, there was a rule that said that if no prototype of a called function was visible, the return type of the function was assumed to be int. This was of course very dangerous and lead to all kind of obscure bugs. Therefore, the implicit int "feature" was removed from the C language 15 years ago, when the standard C99 was released.
Do I really need header files for using libraries?My code works without header files and the libraries are linked perfectly except that I get a "warning: implicit declaration of function"
message.Still its just a warning my program runs.
Header file:- is a file that allows programmers to separate certain elements of a program's source code into reusable files.
A library file is the executable code that works according to what is specified in the header file.
I get a "warning: implicit declaration of function" message.
There may be many reasons for this warning like maybe your header guard is not working right. Another possibility is that you have declared the function Func but called it with func.
Check this out:-
Including a header file is equal to copying the content of the header
file but we do not do it because it will be very much error-prone and
it is not a good idea to copy the content of header file in the source
files, specially if we have multiple source file comprising our
program.
For most of the starters this warning is seen when they start using
malloc
So I am using this example. For the warning in this case You need to add:
#include <stdlib.h>
This file includes the declaration for the built-in function malloc. If you don't do that, the compiler thinks you want to define your own function named malloc and it warns you because:
You don't explicitly declare it and
There already is a built-in function by that name which has a different signature than the one that was implicitly declared (when a function is declared implicitly, its return and argument types are assumed to be int, which isn't compatible with the built-in malloc, which takes a size_t and returns a void*).
My code works without header files and the libraries are linked
perfectly except that I get a "warning: implicit declaration of
function" message.Still its just a warning my program runs.
It is a bad practice to ignore a warning from the compiler. Programs that are not compiled properly could have bugs that might cause you bigger problems and errors in the future.
So for example, if you get a warning:
prog.c:12:5: warning: implicit declaration of /*some function used in the program*/
It is expected that you must include the header file wherein that function is defined.
Do I really need header files for using libraries?
Yes.
My code works without header files
No, it doesn't. It only appears to be working.
and the libraries are linked perfectly except that I get a "warning: implicit declaration of function" message
In this case, I wouldn't call it "perfect".
Still its just a warning my program runs.
And you can never know what it does since it now invokes undefined behavior. "Just a warning"? Sure. There's a reason the compiler warns you. Respect warnings and fix them.
Here's the quote from C99 (6.5.2.2.6) which explains why the program has UB without headers (more precisely, without proper function prototypes which you don't seem to have either):
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.
There's a very good reason header files are used. People who invented and designed the language knew what they were doing, and they made this decision because it's a necessary thing and a good solution to the problem that types need to be visible across compilation units.
I write "hello world" program in C.
void main()
{ printf("Hello World"); }
// note that I haven't included any header file
The program compiles with warning as
vikram#vikram-Studio-XPS-1645:~$ gcc hello.c
hello.c: In function ‘main’:
hello.c:2:2: warning: incompatible implicit declaration of built-in function ‘printf’
vikram#vikram-Studio-XPS-1645:~$ ./a.out
Hello Worldvikram#vikram-Studio-XPS-1645:~$
How is this possible? How does the OS link a library without including any header?
The compiler builds your source file with a reference to a function called printf(), without knowing what arguments it actually takes or what its return type is. The generated assembly contains a push of the address of the string "Hello World" in the static data area of your program, followed by a call to printf.
When linking your object file into an executable, the linker sees a reference to printf and supplies the C standard library function printf(). By coincidence, the argument you have passed (const char*) is compatible with the declaration of the real printf(), so it functions correctly. However, note that the printf() that your program implicitly declares has return type int (I think), which the standard printf() also has; but if they differed, and you were to assign the result of calling printf() to a variable, you would be in the land of undefined behaviour and you would likely get an incorrect value.
Long story short: #include the correct headers to get the correct declarations for functions you use, because this kind of implicit declaration is deprecated, because it is error-prone.
The printf function is in the C library (libc in your case) which is linked implicitly (actually gcc has a printf builtin but it's outside the point).
Including the header doesn't bring in any functions for the linker, it simply informs the compiler about their declarations (i.e. "what they look like").
Obviously you should always include headers otherwise you force the compiler into making assumptions about what the functions look like.
In C, if you use a standard library function, you have to include the standard header where the function is declared. For printf you have to include stdio.h header file.
In C89 (and GNU C89 which is the language by default on gcc), a function declaration can be sometimes omitted because there is a feature called implicit function declaration: when a function identifier foo is used and the function has not been declared, the implementation would use this declaration:
/* foo is a function with an unspecified number of arguments */
extern int foo();
But this declaration is OK only for functions that return int with an unspecified but fixed number of arguments. If the function accepts a variable number of arguments (like printf) such program would invoke an undefined behavior.
Here is what C89/C90 says:
(C90, 6.7.1) "If a function that accepts a variable number of arguments is defined without a parameter type list that ends with the ellipsis notation, the behavior is undefined.
So gcc is kind enough to compile even in C89 and GNU C89: a compiler could refuse to compile.
Also note that
void main() { ... }
is not a valid definition for main (at least on hosted implementations which is probably your case).
If your main function doesn't take any argument use this valid definition:
int main(void) { ... }
The header usually1 contains only function declarations, symbolic constants, and macro definitions; it doesn't usually include function definitions.
All stdio.h gives you is the prototype declaration for printf:
int printf(const char * restrict format, ...); // as of C99
The implementation of printf is in a separate library file that your code links against.
Your code "works" for two reasons:
Under C89 and earlier versions, if the compiler sees a function call
before a declaration or definition of that function, it will assume
that the function returns int and takes an unspecified number of
parameters;
The implementation of printf returns an int, and you passed in
an argument that just happens to be compatible with what the
implementation of printf expects for the first argument.
And to echo what everyone else says, use int main(void) or int main(int argc, char **argv); unless your compiler documentation explicitly lists void main() as a legal signature, using it will invoke undefined behavior (which means everything from your code running with no apparent issues to crashing on exit to failing to load completely).
I say "usually"; I've run across some headers that contained code, but those were usually written by people who didn't know what they were doing. There may be very rare occasions where putting code in a header is justified, but as a rule it's bad practice.
hello.c:2:2: warning: incompatible implicit declaration of built-in function ‘printf’
To deal with this warning, you should include the header file (stdio.h). You're accidently using an old feature of C that has been deprecated since 1999.
Also, the fact that the link doesn't fail simply means that the standard C library is linked in by default. Whether or not you have included the relevant header is immaterial.