tags:

views:

446

answers:

7

I'm trying to understand the purpose behind one header per each source file method. As I see it, headers are meant for sharing function declarations, typedef's and macro's between several files that utilize them. When you make a header file for your .c file it has the disadvantage that each time you want to see a function declaration or macro you need to refer to the header file, and generally it is simpler that everything is in one source file (not the whole software, of course).

So why do programmers use this method?

A: 

Generally a header for a source file method means that you declare only the functions from that compilation unit in that header.

That way you don't pollute with declarations you don't need. (in large software project might be a problem)

As for separate compilation units, these speed up the compilation and can help you avoid collisions if private symbols are declared static.

EFraim
+2  A: 

You don't need one header per source file. One header per module, containing the public interface, and maybe an additional header containing private declarations etc shared between files in that module.

Vicky
+1  A: 

Because, as you said yourself, it is not feasible to put the "whole software" into one source file.

If your program is very small, then yes it's is simpler just to put everything in one .c file. As your program gets larger, it becomes helpful to organize things by putting related functions together in different .c files. Further, in the .h files you can restrict the declarations you give to declarations of things that are supposed to be used by things in other .c files. If a .c file doesn't contain anything that should be accessible outside itself, it needs no header.

For example, if .c has function foo() and fooHelper(), but nobody except foo() is supposed to call fooHelper() directly, then by putting foo() and fooHelper() into foo.c, only putting the declaration of foo() in foo.h, and declaring fooHelper() as static, it helps to enforce that other parts of your program should only access foo() and should not know or care about fooHelper(). Kind of a non object-oriented form of encapsulation.

Finally, make engines are generally smart enough to rebuild only those files which have changed since the last build, so splitting into multiple .c files (using .h files to share what needs to be shared) helps speed up builds.

Tyler McHenry
+1  A: 

You only put in your header file the bare minimum that other source files need to "see" in order to compile. I've seen some people that put everything non-code into the header file (all typedefs, all #define's, all structures, etc.) even if nothing else in the codebase will be using those. That makes the header file much harder to read for yourself and those who want to use your module.

Jim Buck
+3  A: 

The header files in C separate declarations (which must be available to each .c file that uses the functions) from the definitions (which must be in one place). Further, they provide a little modularity, since you can put only the public interface into a header file, and not mention functions and static variables that should be internal to the .c file. That uses the file system to provide a public interface and private implementation.

The practice of one .h file to one .c file is mostly convenience. That way, you know that the declarations are in the .h file, and the definitions in the corresponding .c file.

David Thornley
if I have declarations that need to be shared by several files, and they do not logically correspond one .c file? say, some #define's, that are used by most of the files. Isn't it better to create a header file with all of those? something neutral that doesn't associate with one .c file?
Leif Ericson
Yes. The idea is that each header contains a group of declarations that relate to each other. In most cases it fits that each .c file has a corresponding .h, but you can add extra .h files (e.g. to define global constants or enums). Ultimately, you're in charge of how you use headers to organise your code.
Jason Williams
+4  A: 

Logical, structured organisation and small source files enable:

  • faster, better programming (easier to find and edit the relevant code)
  • easier maintainability & refactoring
  • teamwork (two programmers trying to change the same code at the same time is bad)
  • faster compiles
Jason Williams
+2  A: 

Programmers use this method because it allows them to separate interface from implementation while guaranteeing that client code and implementation agree on the declarations of the functions. The .h file is the "single point of truth" (see Don't Repeat Yourself) about the prototype of each function.

(Client code is the code that #include's the .h file in order to use the exported functions, but does not implement any of the functions in the .h.)

Norman Ramsey