Should every C or C++ file have an associated header file?

17,221

Solution 1

For a start, it would be unusual to have a main.h since there's usually nothing that needs to be exposed to the other compilation units at compile time. The main() function itself needs to be exposed for the linker or start-up code but they don't use header files.

You can have either one header file per C file or, more likely in my opinion, a header file for a related group of C files.

One example of that is if you have a BTree implementation and you've put add, delete, search and so on in their own C files to minimise recompilation when the code changes.

It doesn't really make sense in that case to have separate header files for each C file, as the header is the API. In other words, it's the view of the library as seen by the user. People who use your code generally care very little about how you've structured your source code, they just want to be able to write as little code as possible to use it.

Forcing them to include multiple distinct header files just so they can create, insert into, delete from, and search, a tree, is likely to have them questioning your sanity :-)

You would be better off with one btree.h file and a single btree.lib file containing all of the BTree object files that were built from the individual C files.


Another example can be found in the standard C headers.

We don't know for certain whether there are multiple C files for all the stdio.h functions (that's how I'd do it but it's not the only way) but, even if there were, they're treated as a unit in terms of the API.

You don't have to include stdio_printf.h, stdio_fgets.h and so on - there's a single stdio.h for the standard I/O part of the C runtime library.

Solution 2

  1. Header files are not mandatory.

  2. #include simply copy/paste whatever file included (including .c source files)

  3. Commonly used in real life projects are global header files like config.h and constants.h that contains commonly used information such as compile-time flags and project wide constants.

  4. A good design of a library API would be to expose an official interface with one set of header files and use an internal set of header files for implementation with all the details. This adds a nice extra layer of abstraction to a C library without adding unnecessary bloat.

  5. Use common sense. C/C++ is not really for the ones without it.

Solution 3

Generally it's best to have a header file for each .c file, containing the declarations for functions etc in the .c file that you want to expose. That way, another .c file can include the .h file for the functions it needs, and won't need to be recompiled if a header file it didn't include got changed.

Solution 4

Generally there will be one .h file for each .c/.cpp file.

Solution 5

Bjarne Stroustrup Explains it beautifully in his book "The C++ Programming Language"....

The single header style of physical partitioning is most useful when the program is small and its parts are not intended for separate use. When namespaces are used, the logical structure of the program can still be explained in a single header file.

For larger Programs, the single header file approach is unworkable in a conventional file-based development environment. A change to the common header forces recompilation of the whole program, and updates of that single header by several programmers are error prone. Unless strong emphasis is placed on programming styles relying heavily on namespaces and classes, the logical structure deteriorates as program grows.

An alternative physical organization lets each logical module have its own header defining the facilities it provides. Each .c file then has a corresponding h. file specifying what it provides(its interface). Each .c module includes its own .h file and usually also other .h files that specifies what it needs from other modules in order to implement the services advertised in its interface. This physical organization corresponds to the logical organization of a module. The multiple header approach makes it easy to determine the dependencies. The single header approach forces us to look at every declarations used by any module and decide if its relevant. The simple fact is that maintenance of a code is invariably done with incomplete information and from a local perspective. The better localization leads to less information to compile a module and thus faster compilation..

Share:
17,221
Vicky
Author by

Vicky

Updated on June 12, 2022

Comments

  • Vicky
    Vicky almost 2 years

    Should every .C or .cpp file should have a header (.h) file for it?

    Suppose there are following C files :

    1. Main.C

    2. Func1.C

    3. Func2.C

    4. Func3.C

    where main() is in Main.C file. Should there be four header files

    1. Main.h

    2. Func1.h

    3. Func2.h

    4. Func3.h

    Or there should be only one header file for all .C files?

    What is a better approach?

  • deworde
    deworde about 15 years
    That's effectively programming Java's Interfaces into C++. I quite like it! So will that throw an error if you don't implement SomeMethod() in the inheriting class?
  • Ankit Sharma
    Ankit Sharma about 15 years
    Yep, that is the philosophy. I certainly can't take credit for this approach, a quite brilliant co-worker came up with the paradigm and I have used it ever since. Yep, you will get compile errors if you fail to correctly implement your external interface.
  • Marcin
    Marcin about 15 years
    No +1 from me since you didn't mention templates :(
  • paxdiablo
    paxdiablo about 15 years
    I was concentrating more on the C side, but why would I mention templates, even for C++? I don't see their applicability to what header files are used (they can go into header files but so can typedefs and I don't mention them explicitly).
  • Kugel
    Kugel over 13 years
    This was used throughout Adobe InDesign SDK. I believe it comes from Microsoft COM.
  • Ankit Sharma
    Ankit Sharma over 13 years
    @Kugel Yep, the IUnknown interface is certainly inspired by COM.