Header Files and Libraries - c

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.

Related

How implicit declaration works

When you don't include and use malloc, we get implicit declaration warning.
"warning: incompatible implicit declaration of built-in function ‘malloc’"
This warning is due to fact that compiler assumes malloc defined as int malloc(size) while it is void* malloc(size).
But how does it know about void* malloc(size)? We have not included anything in header files. So how is it comparing it against something that is not included.
And after that, how does my code work? How does it find correct malloc definition and use it?
Is there any sequence order in which function definitions are scanned?
When you call a function f that has never been defined, an implicit declaration like this takes place:
int f();
Note that you can still pass arguments to f, since it was not declared int f(void); (this is for backwards compatibility with K&R C).
Thus, the compiler doesn't "know" that malloc receives a size argument, in fact you can pass it what you want, it doesn't care.
So, the mere fact that the code works is pure luck. In the case of malloc, if the code works, it just means that the size of an integer is the same size as a pointer - no more, no less - so, you can still call malloc and assign its result to a pointer, since no bits were trimmed / are missing.
The true function is found in the linking stage, after compilation takes place. By this time, your code was already compiled with a wrong function prototype. Of course, if the linker can't find the function anywhere in its path, an error is reported and everything is aborted.
For the case of malloc, and other standard library functions, there may be builtin functions to increase performance. There's even an option for gcc to disable builtin functions (-fno-builtin or -fno-builtin-function). From gcc manpage:
GCC normally generates special code to handle certain built-in
functions more efficiently; for instance, calls to "alloca" may become
single instructions that adjust the stack directly, and calls to
"memcpy" may become inline copy loops. The resulting code is often
both smaller and faster, but since the function calls no longer appear
as such, you cannot set a breakpoint on those calls, nor can you
change the behavior of the functions by linking with a different
library. In addition, when a function is recognized as a built-in
function, GCC may use information about that function to warn about
problems with calls to that function, or to generate more efficient
code, even if the resulting code still contains calls to that
function.
So, in the particular case of malloc, this is how the compiler "knows" its usual signature. Try to compile this code with gcc:
int main(void) {
char *a = malloc(12, 13, 14, 15);
return 0;
}
You will see it will abort with a compilation error:
test.c:3: error: too many arguments to function `malloc'
If you use the option -fnobuiltin, the error goes away and the warning is different:
test.c:3: warning: implicit declaration of function `malloc'
This is the same warning you get every time you use a regular function that was not previously defined, because now the compiler is ignoring what he "knows" about these functions. This example uses gcc, but other compilers will have similar behavior.
But how does it know about void* malloc(size)? We have not included anything in header files. So how is it comparing it against something that is not included.
Most modern compilers have a built-in (i. e. hard-coded in the compiler) list of common standard library functions, so the compiler knows what the declaration should be even without the function being declared (explicitly or implicitly) or called.
This does not mean that the correct declaration will be used (because the implicit declaration rule overrides the compilers apparent knowledge), but at least you know that you're doing something wrong.
The exact purpose of these built-ins is that the compiler can warn you if you forget to include a header file. (There other purposes as well, such as the opportunity to perform intrinsic optimization by knowing the semantics/implementation of a built-in function, but those do not apply here.)
The reason you got this specific warning is malloc being a built-in function in this specific compiler (as the warning states). This function receives special treatment from the compiler. The compiler has intrinsic knowledge about how this function has to be declared, so when the implicit declaration contradicts the proper declaration, the warning is issued immediately.
In general case, with ordinary (non-built-in) functions, you will get a similar waning for an implicitly declared function when the compiler actually discovers the first explicit declaration for the same function (assuming there's a mismatch between the two). In that case the warning will be issued later: not at the point of the call, but at the point of explicit declaration. That's the way it works with ordinary functions.
But with such standard (built-in) functions as malloc the compiler allows itself a bit of "cheating".
It doesn't find the correct definition if you don't declare it properly (either with an explicit declaration in your source code, or by including the proper header). It uses a default, implicit declaration for any functions that are called before they're declared. The implicit declaration includes the assumption that the function returns int.
It's then comparing the default declaration with the way that you called the function. It notices that you're assigning the result to a pointer variable rather than an integer, so it warns you that these are incompatible.

Anybody knows why is this compiling successfully?

Anybody knows why is this compiling successfully in C?
int main(){
display();
return 0;
}
void display(){
printf("Why am I compiling successfully?");
}
I thought when declaration is not provided C assume extern int Function_name(arg1,arg2,...){}. Thus this should give an error but however it's working! I know that Ideone is supressing the warnings but my question is why is it just not giving a straight error? (however in C++ it's straight error)
Turn up the warning level in your compiler and you should get 2 warnings,
display not declared, int assumed
and
display redeclared
Edit:
Older versions of C (pre C99) aren't really that bothered about return types or argument types. You could say it's part of the K&R legacy. For instance, if you don't explicitly specify the argument types, the compiler won't check them at all.
C++ is stricter, which IMO is a good thing. I always provide declarations and always specify the argument lists when I code in C.
It's compiling because C uses a lot of defaults to be backwards compatible. In K&R C, you couldn't specify function prototypes, so the compiler would just assume that you know what you're doing when you call a function.
Later (at least ANSI C, but maybe even in C99), C didn't really have a way to distinguish
void display(void);
void display();
so the empty declaration must be accepted as well.
That's why you can call display() without defining it first.
printf() is similar. You will get a linker error if you forget -lc but from the compiler's point of view, the code is "good enough".
That will change as soon as you enable all warnings that your compiler has to offer and it will fail with an error when you disable K&C compatibility or enable strict ANSI checks.
Which is why "C" is often listed as "you shoot yourself into the foot" in "How to Shoot Yourself In the Foot Using Any Programming Language" kind of lists.
it depends of your Cx (C89, C90, C99,...)
for function return values, prior to C99 it was explicitly specified that if no function declaration was visible the translator provided one. These implicit declarations defaulted to a return type of int
Justification from C Standard (6.2.5 page 506)
Prior to C90 there were no function prototypes. Developers expected to
be able to interchange argu-ments that had signed and unsigned
versions of the same integer type. Having to cast an argument, if the
parameter type in the function definition had a different signedness,
was seen as counter to C’s easy-going type-checking system and a
little intrusive. The introduction of prototypes did not completely do
away with the issue of interchangeability of arguments. The ellipsis
notation specifies that nothing is known about the 1590 ellipsis
supplies no information expected type of arguments. Similarly, for
function return values, prior to C99 it was explicitly specified that
if no function declaration was visible the translator provided one.
These implicit declarations defaulted to a return type of int . If the
actual function happened to return the type unsigned int , such a
default declaration might have returned an unexpected result. A lot of
developers had a casual attitude toward function declarations. The
rest of us have to live with the consequences of the Committee not
wanting to break all the source code they wrote. The
interchangeability of function return values is now a moot point,
because C99 requires that a function declaration be visible at the
point of call (a default declaration is no longer provided)
It probably does (assume such declaration as you wrote), but as you are not passing parameters, it just works fine. It's the same like if you declare int main() where it should actually be int main(int argc, char *argv[]).
So probably if you tried to pass some parameters (different from default ones) from main then use them in display it would fail.
BTW, for me it compiles, but generates warning:
$ gcc z.c
z.c:8:6: warning: conflicting types for ‘display’ [enabled by default]
z.c:4:5: note: previous implicit declaration of ‘display’ was here
When I compile with gcc, I get warnings about redeclaration of display, as you would expect.
Did you get warnings?
It might "run" because C doesn't mangle function names (like C++). So the linker looks for a symbol 'display' and finds one. The linker uses this address to run display. I would expect results to not be what you expect all the time.

How does the warning of implicit declaration of any function affect my code ?

See I have made a library which has several .h & several .c files.
Now under some circumstances I have not removed a warning that says
warning: implicit declaration of function ‘getHandle’
Now I want to ask you, does this cause any problem in the binary of my library?
Will it negatively affect the execution of my library on embedded platforms or anywhere else?
In C90, a call to a function with no visible declaration creates an implicit declaration of a function returning int and taking the promoted types of the arguments. If your getHandle function returns a pointer, for example, then the compiler will generate code assuming that it returns an int. Assigning the result to a pointer object should at least trigger another warning. It might work ok (if int and the pointer type are the same size, and int and pointer function results are returned in the same way), or it could go badly wrong (if, for example, int is 32 bits and pointers are 64 bits, or if pointer results are returned in 68K-style address registers).
The C99 standard removed implicit int from the language. Calling a function with no visible declaration is a constraint violation, requiring a diagnostic and possibly causing your program to be rejected.
And if you just fix the problem, you don't have to waste time figuring out how and whether it will work if you don't fix it.
In such a case the compiler cannot verify that the usage of getHandle is proper - that is, whether the return value and the arguments are of the right type and count. It will just accept the way you call it without any explicit statement that this is the right way.
Adding a prototype of the function is a way to tell the compiler that this is the intended usage of the function and it will be a compile-time error not to comply to that.
It may cause some nasty bugs in case there is a mismatch between the way it's called and the way the function expects its arguments. The most likely effect will be a corruption of the stack.
If there isn't a mismatch, it won't make any difference at runtime.

implicit declaration of function

GCC typically yields this warning when the proper header file is not included. This link --> www.network-theory.co.uk/docs/gccintro/gccintro_19.html says that because the function declaration is implicit (rather than explicitly declared via a header) the wrong argument types could actually be passed to the function, yielding incorrect results. I don't understand this. Does this mean the compiler generates code that pushes something, of the machine's word size, onto the stack for the callee to consume, and hopes for the best?
Detail is appreciated.
If the compiler doesn't have specific information about how the argument should be passed, such as when there's no prototype or for arguments that are passed where the prototype have an ellipsis ('...'), the compiler follows certain rules for passing the arguments. These rule basically follow what occurred in pre-standard (or K&R) C - before prototypes were used. Paraphrased from C99 6.5.2.2/6 "Function calls":
* the integer promotions are applied
* if the argument has float type it's promoted to double
After these default argument promotions are applied, the argument is simply copied to wherever the compiler normally copies arguments (generally, the stack). So a struct argument would be copied to the stack.
If the actual function implementation doesn't match how the compiler creates the parameters, then you get undefined behavior (with exceptions for signed/unsigned mismatch if the value can be represented or pointers to char and pointers to void can be mixed/matched).
Also in C90, if the function is implicitly declared (which C99 doesn't permit, though it does permit functions without prototypes), the return value is defaulted as int. Once again, the the actual function returns something else, undefined behavior results.
In classic K&R C, that's pretty much what happened; there were default coercions (anything smaller than (int) was promoted to (int), for example), and for backwards compatibility any function without a prototype is still called that way, but by and large the only indication you got for passing the wrong type was a weird result or maybe a core dump. Which is where you get in trouble, as when the function has a prototype the exact (not coerced/promoted) value is pushed. So if you're passing a (char), if there's a prototype in scope then a single byte is pushed by the caller, otherwise 4 bytes (on most current platforms). If the caller and callee disagree about this, Bad Things happen.

Why strlen function works without #include<string.h>?

Quick question:
strlen[char*] works perfectly regardless whether I #include <string.h> or not
All I get from compiler is a warning about implicit declaration, but functionally it works as intended.
Why is that?
When you invoke undefined behavior, one possible behavior is that the program behaves as you expected it to, one your system, and with the current version of libraries and system software you have installed. This does not mean it's okay to do this. Actually a correct C99 compiler should not allow implicit function declarations; it should give you an error.
The function prototypes in C are not compulsory. They're useful indications to the compiler so that it can do type checking on types which are passed into them. When you don't include string.h, a default signature is assumed for the function which is why you get the warning.
If a function is called without a prototype in scope, the compiler will generate code to call a function which accepts whatever types of parameters are passed and accept an integer result. If the parameters match those the function expects, and if the function returns its result in a way the calling code can handle(*), all will be well. The purpose of prototyping is to ensure that arguments get converted into expected types if possible, and that compilation will fail if they cannot be converted. For example, if a non-prototyped function expects an argument of type 'long' and one attempts to pass an 'int', any of the following may occur:
The program may crash outright
Things may work as expected
The function may execute as though it were passed some arbitrary different parameter value
The program may continue to run, but with arbitrary values corrupting any or all program variables.
The computer may cause demons may fly out the programmer's nose
By contrast, if the function were prototyped, the compiler would be guaranteed to do whatever was necessary to convert the 'int' to a 'long' prior to calling the function.
When C was originally conceived, prototypes didn't exist, and the programmer was responsible for ensuring that all arguments were passed with the precise types expected. In practice, it's a real pain to ensure that all function arguments are always the exact proper types (e.g. when passing the value five to a function that expects a long, one must write it as either "5L" or "(long)5"). Realistically speaking, there's never(**) any reason to rely upon implicit argument types, except with variadic functions.
(*) Any of the things that can happen with incorrect parameter types can happen with incorrect return types, except when a function is expected to return 'int' and the actual return value of the function would fit in an 'int', the results are more likely to be correct than when incorrect parameter types are used.
(**) The only exceptions I can think of would be if one was programming for some really old hardware for which a prototype-aware compiler was unavailable, or if one was programming for a code-golf or similar competition. The latter I consider puzzle-solving rather than programming, and I'm unaware of any hardware people would be interested in using for which the former condition would apply.
Because it's declaration ie equal to so called 'default declaration'. Compiler expects any unknown function to return int and expect parameters as passed at the first time of function usage in code.
Usually this is because another header file which you have included ALSO includes string.h. Obviously it is bad practice to assume that you don't need to include something just because something else does, but it is most likely responsible for this effect.
I guessing it's because in C an int is the default data type returned from a function.
Can you give a fuller code example.
The function prototype is there in include files. So even if you don't include those files, a fixed prototype int function_name(); is written. Now the code of strlen() is there in the library files which are linked at run time, so the function gives correct output (only if it is the only function with a fixed prototype int function_name();).

Resources