getting a warning when main.c file is compiled - c

I wrote a header file containing function prototypes and imported into the main.c file! all though it compiles and runs i get a warning "implicit declaration of function" for only 1 function! with no other warnings related to the other functions which have prototypes declared in the header file! What is the reason for this?

Probably you are using a function that was not declared. Please refer to link

If you call a function without declaring it, the use of the function becomes it's (implicit) declaration and implicit declarations are actually errors in C. Your program only displays it as a warning because your gcc compiler chooses to.
Since all of your other functions work with the given prototypes, I would suggest to review your function declaration and ensure no typos. If you post your code... I will update my answer with a more appropriate response.

To give a clearer answer I would need to see the code, but for a start, you should never include a .c file. for example, in main.c you should include your header using #include, and then if you have a library you are using, you should include the header file in that as well, but not the main.
It may also be that your function is of the incorrect type, or has a different type than specified in the prototype.

Related

How does GCC compiler find the header file corresponding to some implicitly declared functions?

In the case of an implicitly declared function, gcc will sometimes tell you the header file from which the function belongs. From this answer, it seems only some functions are built in - "some compilers contain built-in declarations for them so they can do some basic type checking".
Is this how gcc is able to tell you which header file corresponds to some implicitly declared functions and not others?
For example,
implicit printf usage will generate an additional comment:
compilation.c:4:5: note: include the header <stdio.h> or explicitly provide a declaration for 'printf'
but bsearch from stdlib does not:
compilation.c:5:5: error: implicit declaration of function 'bsearch' is invalid in C99 [-Werror|,-Wimplicit-function-declaration]
how gcc is able to tell you which header file corresponds to some implicitly declared functions and not others?
Gcc has a list of symbols and headers. When the symbol is encountered and it is not defined and it is in the list, then a message is displayed with the proposed header name.
See the list at https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/gcc/c-family/known-headers.cc#L157 from gcc sources.
bsearch is not in the list, so the hint is not displayed. I like the hints, it would be nice for me to include all the symbols from C standard, including bsearch. It would also be a speedup if the list would be sorted and would use bsearch. You can contribute to gcc or donate to gcc and write about it to gcc mailing list.

weird static function behaviour

i am looking at static functions, i know they have a scope limited to the file they are declared in. For clarification i use code blocks with GCC. If i declare the function in a ..c file and include it in my main.c file, the function can be accessed (but the compiler will complain if a non static function is defined, as i have multiple definitions). However if i have a c file with some static function and another non-static function, then the static function is not accessible and the non-static function is accessible. This to me is a rather weird. I know that the #include directive copies the contents of the to-be-included file in to the file where the include directive is declared. But then why can i access the non-static function without including the .c file in the main.c file?
Any suggestions on where i could read up on this topic? I am thinking it has something to do with linking, but i may be wrong.
When a function is declared without static, it has external linkage.1 This means that, when the program is linked2, the same name in different translation units3 can be made to refer to the same thing.
When you define a function in one source file, say int square(int x) { return x*x; }, compiling that source file produces an object file that contains information saying “The function foo is defined here.” When you declare a function in another source file and use that function, such as int square(int x); … b = square(a);, compiling that source file produces an object file that contains information saying “The function foo is used here.” When the linker or program loader processes these object files, it modifies the place where foo is used to refer to the place where foo is defined.
If you use a function without declaring it in that translation unit, your compiler might provide a default declaration for the function, as if it had been declared to return int with no information about its parameters. This behavior is a legacy of old versions of C. Quite likely your compiler issues a warning such as “implicit declaration of function” for this. You should not ignore this warning. When it appears, find the code causing the warning and fix it—either correct the typing of a misspelled function name or insert a declaration for the function.
When using GCC or Clang, you should use the switch -Werror to elevate warnings to errors, so that the compiler will not compile programs that cause warning messages. While this may at first make it more of a nuisance to get your programs compiled, it causes you to fix errors early and to learn to program correctly.
Footnotes
1 With static, an identifier for a function has internal linkage. The rules for identifiers for objects (which you may think of as variables) are more complicated, and they can also have no linkage.
2 In practice, each compilation produces an object module. Linking combines object modules to make an executable program or, in complicated builds, new object modules.
3 A translation unit is the source file being compiled including all the files it includes with #include statements.
So I found a decent answer to your question in a different stackoverflow question, but before I get to that I want to explain why including .c files is bad practice, and shouldn't be done:
As you pointed out, #include copies the content of the file. This means that you can't include the .c file more than once, since you would be creating >1 instance of the same function (of the same name).
If you try to create a universal .c file, say, math.c, you can't create any other .c files that use any of its functions, since you can only include it once, and thats reserved for your main.c file. This severely limits the usefulness of every function in your .c files
instead, you should only ever include header files (.h). You declare your functions in your .h file, define in your .c file.
Whatever functions you declare in your .h file, you can then use in any other files where said .h file is included, without causing compiler errors
I get that this is confusing, but here's examples from another stackoverflow thread
here's a further better document explaining how header files (.h) work
Why can you access non-static function despite not including the .c file?
this should not be possible generally in c if you're not explicitly including said .c file. If I were to do that I would get an "implicit declaration" function, because the compiler doesn't recognize the functions, as they've not been declared previously.
relevant stack overflow answer
long story short, declaring a function static in a .c file means that its scope is limited only to said .c file, you can't call it anywhere else

Importance of function prototype (declarations) in header files [duplicate]

This question already has answers here:
Are prototypes required for all functions in C89, C90 or C99?
(6 answers)
Closed 5 years ago.
I was writing some code in a project spanning multiple *.c and *.h files (i guess I can call the *.c and *.h as modules or programs) and forgot to declare a newly created "getter" function in the header file for particular module/program. The header file was included in another module which needed access to that getter function.
Somehow the program worked fine!
I would like to know what is the importance of the declaring function prototypes in the header if the linker is able link object files to sort things out for itself. Duplicate function resolution??? This would mean that linker links by function name by matching it to what is called in function.
How does linker treat the extern variables?
C used to allow implicit declarations of functions. If a function was not declared when it was called, the compiler used the call to deduce (guess) the declaration. This deduction may be correct, or it may be wrong, and if it's wrong then that will lead to undefined behavior when you run the program.
With a proper prototype declaration the compiler doesn't have to guess.
The prototype tells the compiler the involved types (return value and arguments) of the function. Without a prototype, they are all implicitly int. This might work for some functions, but is deprecated in standard C (and disallowed starting from C99; it was common in pre-standard C), so you should always have a declared prototype for any function you call. A good compiler will warn you if you enable warnings. E.g. for gcc, always use something like -std=c11 -Wall -Wextra -pedantic (or some older C standard for -std) to get useful warnings.

What's the benefit for a C source file include its own header file

I understand that if a source file need to reference functions from other file then it needs to include its header file, but I don't understand why the source file include its own header file. Content in header file is simply being copied and pasted into the source file as function declarations in per-processing time. For source file who include its own header file, such "declaration" doesn't seem necessary to me, in fact, project still compile and link no problem after remove the header from it's source file, so what's the reason for source file include its own header?
The main benefit is having the compiler verify consistency of your header and its implementation. You do it because it is convenient, not because it is required. It may definitely be possible to get the project to compile and run correctly without such inclusion, but it complicates maintenance of your project in the long run.
If your file does not include its own header, you can accidentally get in a situation when forward declaration of a function does not match the definition of the function - perhaps because you added or removed a parameter, and forgot to update the header. When this happens, the code relying on the function with mismatch would still compile, but the call would result in undefined behavior. It is much better to have the compiler catch this error, which happens automatically when your source file includes its own header.
Practical example - assume the following files in a project:
/* foo.h */
#ifndef FOO_H
#define FOO_H
double foo( int x );
#endif
/* foo.c */
int foo( int x )
{
...
}
/* main.c */
#include "foo.h"
int main( void )
{
double x = foo( 1 );
...
}
Note that the declaration infoo.h does not match the definition in foo.c; the return types are different. main.c calls the foo function assuming it returns a double, according to the declaration in foo.h.
foo.c and main.c are compiled separately from each other. Since main.c calls foo as declared in foo.h, it compiles successfully. Since foo.c does not include foo.h, the compiler is not aware of the type mismatch between the declaration and definition, so it compiles successfully as well.
When you link the two object files together, the machine code for the function call won't match up with what the machine code for function definition expects. The function call expects a double value to be returned, but the function definition returns an int. This is a problem, especially if the two types aren't the same size. Best case scenario is you get a garbage result.
By including foo.h in foo.c, the compiler can catch this mismatch before you run your program.
And, as is pointed out in an earlier answer, if foo.h defines any types or constants used by foo.c, then you definitely need to include it.
The header file tells people what the source file can do.
So the source file for the header file needs to know its obligations. That is why it is included.
Yours seems a borderline case, but an include file can be viewed as a sort of contract between that source file and any other source files that may require those functions.
By writing the "contract" in a header file, you can ensure that the other source files will know how to invoke those functions, or, rather, you will be sure that the compiler will insert the correct code and check its validity at compile time.
But what if you then (even inadvertently) changed the function prototype in the corresponding source file?
By including in that file the same header as everyone else, you will be warned at compile time should a change inadvertently "break" the contract.
Update (from #tmlen's comment): even if in this case it does not, an include file may also use declarations and pragmas such as #defines, typedef, enum, struct and inline as well as compiler macros, that would make no sense writing more than once (actually that would be dangerous to write in two different places, lest the copies get out of sync with each other with disastrous results). Some of those (e.g. a structure padding pragma) could become bugs difficult to track down.
It is useful because functions can be declared before they are defined.
So it happens that you have the declaration, followed by a call\invocation, followed by the implementation.
You don't have to, but you can.
The header file contains the declarations. You're free to invoke anytime as long as the prototype matches. And as long as the compiler finds an implementation before finishing compilation.

Will there be any error if h file includes signature which has no c file implementation?

Should there be any errors, if a .h file contains a signature, which has no implementation in a .c file?
If you use the function, and it isn't implemented, you will get a link error. Otherwise, no errors or warnings will occur.
No, it is not an error to declare a function and not define it.
If you enable warnings, you may get a warning if you define a function with static linkage that does not get used in this translation unit.

Resources