importance of header files [duplicate] - c

This question already has answers here:
What is the point of header files in C? [duplicate]
(4 answers)
Closed 9 years ago.
Is there a need to create a header file after making a source file? What are the things included in a header file? is it necessary or is it good for only source files containing a function definition?
I'm really confused since what you put in header files, such as function portotypes, can also be placed in a source file. Are header files only good for declaring global variables? Is creating a header file with the same name as your source file necessary.
I already got the answer of "What are header files for". Apparently a lot of questions similar to this have been posted that's why adding some follow up questions.

I guess you could search on Google and find whatever your need to know but to make it short:
In C (and C++), every source (.c or .cpp) file is compiled on its own translation unit. This means that every file is compiled on its own to produce an object file. Once all object files are compiled, they are linked together to create your final binary file.
This means that a source file has no clue of what's defined in other source files, the header file is needed to fill this gap: it provides the declarations of variables, functions and whatever that are implemented in one or many source files, so that, when you are including it inside another source file, the compiler can verify that all these external things are correctly used. This is not its only purpose, it can aid in other taks (like reuse of code or partitioning) but this is why it exists.
The header file is literally included when you use the #include directive.

Related

What is the point of linking 2 source files instead of using a header file?

Why should I use another source code file to share code or a function between many programs and use the linker instead of using a header file only? (I read this in Head First C but I didn't understand what is the point of it)
Generally, header files should only be used to declare your functions/structs/classes.
The actual implementation should be created in a separate .c file which then can be built and exported as a binary along with the header.
Keeping the implementation in the header has many drawbacks.
Bigger footprint - the header size will be bigger since you have
more symbols in it.
You cannot hide the implementation from the end-user.
The compile-time will be a lot larger since all code has to be processed every time it is included by the compiler.
Just to name a few. They might be many more reasons.
However, there are some cases when it is okay/better to include some logic in the header files.
For example for inline functions which may improve the runtime of the application while maintaining good code quality and/or templates in C++.
Generally, header files contain declarations, like function signatures, while the function definitions (the actual source code) are located in separate source files.
Multiple files can include the same header file and share function declarations at compile time. But they also must share the source files (the files must be linked together) in order to have access to the function code at run time.

Why header files are needed in c [duplicate]

This question already has answers here:
What is the point of header files in C? [duplicate]
(4 answers)
Closed 3 years ago.
When I program in c there are .h files .
Header files contain the signatures of functions that are implement in c files.
Why are header files are needed as I can include the c file to use the function there instead of using headers.
Is this to make the compiler's job easier?
TLDR answer is organization and code reuse.
Header files contain common standard code usable across multiple code bases - think of them as libraries to bring in.
This code is kept separate for maintenance issues. You only want one copy, so when a fix needs making it happens in one place. All of the various code bases you have that reference that one included header file suddenly have the updates.
You can also do project specific headers. For example, my SQL statements are all static strings, since they are long and complex I keep them in a different file and just include it. This way, I don't have a large long blob of complex SQL as a string in the middle of my code.

#include in header files in embedded [duplicate]

This question already has answers here:
Should I use #include in headers?
(9 answers)
Closed 6 years ago.
I am reading through an embedded C standard book and I noticed the following:
No header file shall contain an #include statement
What should I do with function declarations that have non-standard types?
example: void function(some_funky_type x);
Throw that book away; it is absolute garbage. In fact, you should burn it, to make sure no other poor soul ever picks it up.
Header files should absolutely include all of the header files necessary for them to be self-sufficient. There is nothing worse than trying to carefully massage the order of your #include statements to be sure that the types needed by one are already defined before it is included.
This is a stupid and counterproductive rule for precisely the reason you identified. The alternative is for every .c file to include all of the .h files that a subsequently included header will require. You can imagine that if you introduce a new dependency in a commonly included header that you will now have to update every C file that includes that header.

Why including a header file and not the implementation? [duplicate]

This question already has answers here:
Header per source file
(7 answers)
Closed 8 years ago.
On most tutorial I could find on the web I have notice that everyone is creating header files for everything and never include a .c file.
I couldn't find any good explanation on the web about why you need the header file.
I have read that including the header file allows you to not repeat yourself which doesn't make sense to me. The header file IS a repetition of all the declaration of your implementation, if you include your implementation directly, then you avoid this overhead right!?!
Don't get me wrong, I can understand the use of header file when you are doing libraries : Several project can include only the header file and then linking to the same library (e.g. the standard library) thus ending up with a smaller executable. I just don't see the benefit of header file when you include something which is completly specific to your project...
Can you explain me the real benefit of header files?
Suppose you have a program built from 10 source files. If each one included all the code that was needed (including, presumably, the implementations of the standard C library functions it uses), you'd have lots and lots of multiple definition errors when you link all the bits together.
So, a header (normally) includes just the declarations. The object code for the corresponding source code is linked with the program, either as explicit object files or as libraries. This stops you getting multiple definition errors.

Organization of C files

I'm used to doing all my coding in one C file. However, I'm working on a project large enough that it becomes impractical to do so. I've been #including them together but I've run into cases where I'm #including some files multiple times, etc. I've heard of .h files, but I'm not sure what their function is (or why having 2 files is better than 1).
What strategies should I use for organizing my code? Is it possible to separate "public" functions from "private" ones for a particular file?
This question precipitated my inquiry. The tea.h file makes no reference to the tea.c file. Does the compiler "know" that every .h file has a corresponding .c file?
You should regard .h files as interface files of your .c file. Every .c file represents a module with a certain amount of functionality. If functions in a .c file are used by other modules (i.e. other .c files) put the function prototype in the .h interface file. By including the interface file in your original modules .c file and every other .c file you need the function in, you make this function available to other modules.
If you only need a function in a certain .c file (not in any other module), declare its scope static. This means it can only be called from within the c file it is defined in.
Same goes for variables that are used across multiple modules. They should go in the header file and there they have to marked with the keyword 'extern'. Note: For functions the keyword 'extern' is optional. Functions are always considered 'extern'.
The inclusion guards in header files help to not include the same header file multiple times.
For example:
Module1.c:
#include "Module1.h"
static void MyLocalFunction(void);
static unsigned int MyLocalVariable;
unsigned int MyExternVariable;
void MyExternFunction(void)
{
MyLocalVariable = 1u;
/* Do something */
MyLocalFunction();
}
static void MyLocalFunction(void)
{
/* Do something */
MyExternVariable = 2u;
}
Module1.h:
#ifndef __MODULE1.H
#define __MODULE1.H
extern unsigned int MyExternVariable;
void MyExternFunction(void);
#endif
Module2.c
#include "Module.1.h"
static void MyLocalFunction(void);
static void MyLocalFunction(void)
{
MyExternVariable = 1u;
MyExternFunction();
}
Try to make each .c focus on a particular area of functionality. Use the corresponding .h file to declare those functions.
Each .h file should have a 'header' guard around it's content. For example:
#ifndef ACCOUNTS_H
#define ACCOUNTS_H
....
#endif
That way you can include "accounts.h" as many times as you want, and the first time it's seen in a particular compilation unit will be the only one that actually pulls in its content.
Compiler
You can see an example of a C 'module' at this topic - Note that there are two files - the header tea.h, and the code tea.c. You declare all the public defines, variables, and function prototypes that you want other programs to access in the header. In your main project you'll #include and that code can now access the functions and variables of the tea module that are mentioned in the header.
It gets a little more complex after that. If you're using Visual Studio and many other IDEs that manage your build for you, then ignore this part - they take care of compiling and linking objects.
Linker
When you compile two separate C files the compiler produces individual object files - so main.c becomes main.o, and tea.c becomes tea.o. The linker's job is to look at all the object files (your main.o and tea.o), and match up the references - so when you call a tea function in main, the linker modifies that call so it actually does call the right function in tea. The linker produces the executable file.
There is a great tutorial that goes into more depth on this subject, including scope and other issue you'll run into.
Good luck!
-Adam
A couple of simple rules to start:
Put those declarations that you want to make "public" into the header file for the C implementation file you are creating.
Only #include header files in the C file that are needed to implement the C file.
include header files in a header file only if required for the declarations within that header file.
Use the include guard method described by Andrew OR use #pragma once if the compiler supports it (which does the same thing -- sometimes more efficiently)
To answer your additional question:
This
question precipitated my inquiry. The
tea.h file makes no reference to the
tea.c file. Does the compiler "know"
that every .h file has a corresponding
.c file?
The compiler is not primarily concerned with header files. Each invocation of the compiler compiles a source (.c) file into an object (.o) file. Behind the scenes (i.e. in the make file or project file) a command line equivalent to this is being generated:
compiler --options tea.c
The source file #includes all the header files for the resources it references, which is how the compiler finds header files.
(I'm glossing over some details here. There is a lot to learn about building C projects.)
As well as the answers supplied above, one small advantage of splinting up your code into modules (separate files) is that if you have to have any global variables, you can limit their scope to a single module by the use of the key word 'static'. (You could also apply this to functions). Note that this use of 'static' is different from its use inside a function.
Your question makes it clear that you haven't really done much serious development. The usual case is that your code will generally be far too large to fit into one file. A good rule is that you should split the functionality into logical units (.c files) and each file should contain no more than what you can easily hold in your head at one time.
A given software product then generally includes the output from many different .c files. How this is normally done is that the compiler produces a number of object files (in unix systems ".o" files, VC generates .obj files). It is the purpose of the "linker" to compose these object files into the output (either a shared library or executable).
Generally your implementation (.c) files contain actual executable code, while the header files (.h) have the declarations of the public functions in those implementation files. You can quite easily have more header files than there are implementation files, and sometimes header files can contain inline code as well.
It is generally quite unusual for implementation files to include each other. A good practice is to ensure that each implementation file separates its concerns from the other files.
I would recommend you download and look at the source for the linux kernel. It is quite massive for a C program, but well organised into separate areas of functionality.
The .h files should be used to define the prototypes for your functions. This is necessary so you can include the prototypes that you need in your C-file without declaring every function that you need all in one file.
For instance, when you #include <stdio.h>, this provides the prototypes for printf and other IO functions. The symbols for these functions are normally loaded by the compiler by default. You can look at the system's .h files under /usr/include if you're interested in the normal idioms involved with these files.
If you're only writing trivial applications with not many functions, it's not really necessary to modularize everything out into logical groupings of procedures. However, if you have the need to develop a large system, then you'll need to pay some consideration as to where to define each of your functions.

Resources