How to check validity of header file in C programming language - c

Is there a way in C programming language to check if function prototypes from a header files corresponds to actual function definition in compile time.
For example, if I made header file, and then change signature of some function described in that header file, can I check in compile time if there is a wrong prototype in header file? Is that a job of the compiler or some other tool before compilation?
Thanks.

If you declare the same function name with two different prototypes, the compiler should catch this, i.e.:
int foo(int a, int b);
...
int foo(int a, float b) { ... }
Of course, if you actually rename the function, then the compiler cannot catch it, i.e.:
int foo(int a, int b);
...
int fee(int a, int b) { ... }
Unless, of course, you attempt to call foo from elsewhere. Then the linker will complain.

That is the job of the compiler and in my experience it does it quite well:)
If your function prototype in header file does not match it's definition in the source file, then you cannot use that function in other source file because it is not declared and the compiler will inform you so, by giving an error.

If you use the function, the compiler will give you a linker error, if an implementation for a prototype does not exists. But if you never use the function (for example when you build a library) the linker will not complain.
This is one of the reasons you should make sure you have good code coverage in your tests - if you have for example some unit tests which also gets compiled, the linker will complain. If you have some functions you can not test and will not get called from within your code, you can just write a dummy executable (which does not have to work) which will call all this functions.
The last solution would be to use the clang libraries to write your own code checkers.

Related

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.

How do you create general personalized functions in C and then include them in your program?

I'm a beginner to C, but I've had a bit of experience with some other programing languages like Ruby and Python. I would very much like to create some of my own functions in C that I could use in any of my programs that just make life easier, however I'm a little bit confused about how to do this.
From what I understand the first part of this process is to create a header file that contains all of your prototypes, and I understand that, however from what I understand it is frowned upon to include anything other than declarations in your header files, so would you also need to create a .c file that contained the actual code and then #include that in all your programs along with the header file? But if so, why would you need a header file in the first place, since defining a function also declares it?
Finally, what should you put in the main() function of your header file? Do you just leave it blank, or do you not include it?
Thanks!
The declaration of a function lets the compiler know that at link time such a function will be available. The definition of the function provides that implementation, and additionally it also serves as the declaration. There is no harm in having multiple declarations, but only one implementation can be provided. Also, at least one declaration (or the only implementation) must come before any use of the function - this alone makes forward declarations necessary in cases where two functions call one another (both cannot be before the other).
So, if you have the implementation:
int foo(int a, int b) {
return a * b;
}
The corresponding declaration is simply:
int foo(int a, int b);
(The argument names do not matter in the declaration, i.e., they can be omitted or different than in the implementation. In fact you could declare only int foo(); and it would work for the above function, but this is mainly a legacy thing and not recommended. Note that to declare a function that takes no arguments, put void in the argument list, e.g., int bar(void);)
There are a number of reasons why you would want to have separate headers with only the declaration:
The implementation may be in a separate file, which allows for organisation of code into manageable pieces, and may be compiled by itself and need not be recompiled unless that file has changed - in large projects where the total compilation time can be an hour it would be absurd to re-compile everything for a small change.
The implementation source may not be available, e.g., in case of a closed-source proprietary library.
The implementation may be in a different language with a compatible calling convention.
For practical details on how to write code in multiple files and how to use libraries, please consult a book or tutorial on C programming. As for main, you need not declare it in a header unless you are specifically calling main from another function - the convention of C programs is to call main as int main(int, char**) at start of the execution.
When compiling, each .c-file (or .cpp-file) will be compiled to an own binary first.
If one binary file is using functions from another,
it just knows "there is something outside named xyz" at that time.
Then the linker will put them together in one file and rewrite the parts of each file
which are using functions of other files,
so that they actually know where to find the used functions.
What will happen if you put code in a .h file:
At compilation time, each included h-file in a c-file will be integrated in the c-file.
If you have code for xyz in a h-file and you´re including it in more thana one c-file,
each of this compiled c-files will have a xyz. Then, the linker will be confused...
So, function code have to be in a own c file.
Why use a h-file at all?
Because, if you call xyz in your code, how should the compiler know
if this is a function of another c-file (and which parameters...)
or an error because xyz does not exist?
The reason for header files in c are for when you need the same code in multiple scripts. So if you are just repeated the same code in one script then yes it would be easier to just use a function. Also for header files, yes you would need to include a .c file for all the computations.

inlining a function

I am developing in C using gcc in Linux.
I am organizing my small functions in .H and .C files in the following way
// .H file
extern int my_function( int val );
// .C file
inline int my_function( int val ){
// my job..very short!
}
These functions are small so they are very good candidates to be inlined but I don't know if they will be for sure.
I have doubt about the way I cam organizing my file and I was thinking that probably it would be better to have all my functions inlined directly into the .h file without .C file.
Can you help me a bit in clarifying my doubt?
First of all, note that you can tell gcc to try and inline small functions into their callers by adding the -finline-functions option.
If you have any doubt that your function will actually be inlined, you can ask gcc to warn you about uninlinable function, by using -Winline
Here, as your functions are declared both extern and inline, they will be inlined as the inline definition will only be used for inlining. In this particular situation the function will not be compiled on its own at all.
Read http://gcc.gnu.org/onlinedocs/gcc/Inline.html for further details.
No matter how small your function is, the choice is compiler's whether or not to inline it.
So even if you have very few number of functions and you inline them all in your code, there's still no guarantee that all will be inlined by the compiler.
You can find some useful inshgts on inlining here.
First, the compiler must be able to see the definition of a function in order to inline it. Hence, you must place the definition in the header file. (Here, I'm assuming your application consists of more than one source file). Note: Some development environments support multi-file compilation, in which case this remark does not apply.
Secondly, the semantics of inline C99 is a bit confusing if you are accustomed C++ (where things "just work"). In C99, you must single out a single source file (not header file) which own the function -- in case the function is not inlined in some source file, there must exist exactly one explicit definition of the function. This is done by specifying the function using the extern keyword. (This is a deviation from the traditional interpretation of extern, that it was used for declarations only).
For example:
// .h file
inline int my_function( int val )
{
// my job..very short!
}
// In ONE .c file
extern int my_function( int val );

C: Pointer to inline function

I have a static inline function defined in an H file, and at one point in a C file, I'm assigning a pointer to the function, something like this:
foo.h:
static inline void frobnicate(void) {
// frobs something.
}
foo.c
#include "foo.h"
void execute(void (*func)(void) ) {
func();
}
void blahBlahBlah(void) {
execute(frobnicate);
}
bar.c
#include "foo.h"
// ...
frobnicate();
So I think what will happen here is that the compiler will inline the call to frobnicate from bar.c, but in foo.c, it will actually have to create a function to implement frobnicate, so that it can have a working pointer to it.
Can anyone confirm if my understanding is accurate, and correct me otherwise?
inline is one of the misnomers of the C standard. Its main meaning is to be able to put the definition of a function in a header file without having to deal with "multiple definition" problems at link time.
The official way in C99 and C11 to do what you want to achieve is to have the inline definition in the header file, without the static. Since you also need the symbol to be emitted you need to tell the compiler in which compilation unit this should be. Such an instantiation can be done by have a declaration in that .c file where you omit the inline keyword.
Most naturally you could use the .c file where you actually need the symbol.
Yes, you are right. When you take the pointer to the function the compiler must create an "stand alone" version where the code can be called as a normal function.
The benefit of inlining a function is that the calling code need not to be created and any other optimization can be aplied to integrate both the caller function and the inlined function. But when you need to do a regular call to the function(as when you take the address to call it latter), those optimizations are not possible anymore.

How does splint know my function isn't used in another file?

Splint gives me the following warning:
encrypt.c:4:8: Function exported but not used outside encrypt: flip
A declaration is exported, but not used outside this module. Declaration can
use static qualifier. (Use -exportlocal to inhibit warning)
encrypt.c:10:1: Definition of flip
Since I called splint only on this file how does it know that?
#include <stdio.h>
#include <stdlib.h>
int flip( int a)
{
int b;
b = a;
b ^= 0x000C;
return b;
}
int blah(int argc, char *argv[]) {
FILE *fp = NULL, *fpOut=NULL;
int ch;
ch = 20; flip(20); return (ERROR_SUCCESS);
}
I even got rid of main so that it could not figure out that the file is complete in any way. I am totally stumped!
You might find that if you included a header that declared flip() - as you should, of course - then splint would not complain. You should also declare blah() in the header as well.
I'm not wholly convinced that this is the explanation because blah() is not used at all (though it uses flip()) and you don't mention splint complaining about that.
However, it is a good practice to make every function (in C) static until you can demonstrate that it is needed outside its source file, and then you ensure that there is a header that declares the function, and that header is used in the file that defines the function and in every file that uses the function.
In C++, the 'every function should be static' advice becomes 'every function should be defined in the anonymous namespace'.
Since I called splint only on this file how does it know that?
You have answered your question. You've fed in one file to lint, so lint knows there is only file to be taken care of (apart from the standard header includes, of course).
int flip() is not declared as static, so it can be potentially used externally. Since you invoked splint with only one source file, it correctly says that your function, if not used externally, must be declared static
It can only report on what it sees. Ignore the warning or follow the instructions to inhibit it if you know better than what it says. Don't assume that a tool like this necessarily knows your program better than you do.
If it really is not intended to be used outside of the file, you can declare it static and it should correct the problem, but it will be inaccessible from other files.

Resources