tags:

views:

1202

answers:

14

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

Suppose there are following C files :

Main.C

Func1.C

Func2.C

Func3.C

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

Main.h

Func1.h

Func2.h

Func3.h

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

What is a better approach?

+2  A: 

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

Trent
+3  A: 

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.

Khoth
In other words, it's unusual to have a main.h since there's usually nothing that needs to be exposed to the other compilation units at compile time. main() itself needs to be exposed for the linker/startup-code but they don't use header files.
paxdiablo
+3  A: 

It depends. Usually your reason for having separate .c files will dictate whether you need separate .h files.

jmucchiello
+17  A: 

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

You can have either one header file per C file or, most likely, 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 make sense in that case to have separate header files for each C file as the header is the API, the view of the library to the user. I doubt the user would want to include 6 header files just to be able to use the functions. There would be one btree.h file and a single btree.lib file containing all of the BTree objects 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 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.

paxdiablo
No +1 from me since you didn't mention templates :(
Marcin
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).
paxdiablo
+1  A: 

There is no better approach, only common and less common cases.

The more common case is when you have a class/function interface to declare/define. It's better to have only one .cpp/.c with the definitions, and one header for the declarations. Giving them the same name makes easy to understand that they are directly related.

But that's not a "rule", that's the common way and the most efficient in almost all cases.

Now in some cases( like template classes or some tiny struct definition ) you'll not need any .c/.cpp file, just the header. We often have some virtual class interface definition in only a header file for example, with only virtual pure functions or trivial functions.

And in other rare cases (like an hypothetical main.c/.cpp file) if wouldn't be always required to allow code from external compilation unit to call the function of a given compilation unit. The main function is an example (no header/declaration needed), but there are others, mostly when it's code that "connect all the other parts together" and is not called by other parts of the application. That's very rare but in this case a header make no sense.

Klaim
A: 

As already noted, generally, there will be one header (.h) file for each source (.c or .cpp) file.

However, you should look at the cohesiveness of the files. If the various source files provide separate, individually reusable sets of functions - an ideal organization - then you should certainly have one header per file. If, however, the three source files provide a composite set of functions (that is too big to fit into one file), then you would use a more complex organization. There would be one header for the external services used by the main program - and that would be used by other programs needing the same services. There would also be a second header used by the cooperating source files that provides 'internal' definitions shared by those files.

(Also noted by Pax): The main program does not normally need its own header - no other source code should be using the services it provides; it uses the services provided by other files.

Jonathan Leffler
A: 

If you want your compiled code to be used from another compilation unit you will need the header files. There are some situations for which you do now need/want to have a headers.

The first such case are main.c/cpp files. This class is not meant to be included and as such there is no need for a header file.

In some cases you can have a header file that defines behavior of a set of different implementations that are loaded through a dll that is loaded at runtime. There will be different set of .c/.cpp files that implement variations of the same header. This can be common in plugin systems.

David Rodríguez - dribeas
+6  A: 
  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.

Subtwo
A: 

Generally cpp/c files are for implementation and h/hpp (hpp are not used often) files are for header files (prototypes and declarations only). Cpp files don't always have to have a header file associated with it but it usually does as the header file acts like a bridge between cpp files so each cpp file can use code from another cpp file.

One thing that should be strongly enforced is the no use of code within a header file! There's been too many times where header files break compiles in any size project because of redefinitions. And that's simply when you include the header file in 2 different cpp files. Header files should always be designed to be included multiple times as well. Cpp files should never be included.

Jeremy Edwards
A: 

In general, I don't think there is any explicit relationship between .h and .c files. In many cases (probably most), a unit of code is a library of functionality with a public interface (.h) and an opaque implementation (.c). Sometimes a number of symbols are needed, like enums or macros, and you get a .h with no corresponding .c and in a few circumstances, you will have a lump of code with no public interface and no corresponding .h

in particular, there are a number of times when, for the sake of readability, the headers or implementations (seldom both) are so big and hairy that they end up being broken into many smaller files, for the sake of the programmer's sanity.

TokenMacGuy
+1  A: 

I like putting interfaces into header files and implementation in cpp files. I don't like writing C++ where I need to add member variables and prototypes to the header and then the method again in the C++. I prefer something like:

module.h

struct IModuleInterface : public IUnknown
{
    virtual void SomeMethod () = 0;
}

module.cpp

class ModuleImpl : public IModuleInterface,
          public CObject // a common object to do the reference
                                              // counting stuff for IUnknown (so we
                                              // can stick this object in a smart 
                                              // pointer).
{
    ModuleImpl () : m_MemberVariable (0)
    {
    }

    int m_MemberVariable;

    void SomeInternalMethod ()
    {
     // some internal code that doesn't need to be in the interface
    }

    void SometMethod ()
    {
     // implementation for the method in the interface
    }

    // whatever else we need
};

I find this is a really clean way of seperating implementation and interface.

Cannonade
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?
deworde
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.
Cannonade
+1  A: 

It's all about what code needs to be aware of what other code. You want to reduce the amount other files are aware of to the bare minimum for them to do their jobs.

They need to know that a function exists, what types they need to pass into it, and what types it will return, but not what it's doing internally. Note that it's also important from the programmers point of view to know what those types actually mean. (e.g which int is the row, and which is the column) but the code itself doesn't care. This is why naming the function and parameters sensibly is worthwhile.

As others have said, if there's nothing in a cpp file worth exposing to other parts of the code, as is normally the case with main.c, then there's no need for a header file.

It's occasionally worth putting everything you want to expose in a single header file (e.g, Func1and2and3.h), so that anything that knows about Func1 knows about Func2 as well, but I'm personally not keen on this, as it means that you tend to load a hell of a lot of junk along with the stuff you actually want.

Summary: Imagine that you trust that someone can write code and that their algorithms, design, etc. are all good. You want to use code they've written. All you need to know is what to give them to get something to happen, what you should give it to, and what you'll get back. That's what needs to go in the header files.

deworde
+1  A: 

If your file exposes an interface - that is, if it has functions which will be called from other files - then it should have a header file. Otherwise, it shouldn't.

Gilad Naor
+4  A: 

I used to follow the "it depends" trend until I realized that consistency, uniformity and simplicity are more important than saving the effort to create a file, and that "standards are good even when they are bad".

What I mean is the following: a .cpp/.h pair of files is pretty much what all "modules" end up anyway. Making the existing of both a requirement saves a lot of confusion and bad engineering.

For instance, when I see some interface of something in a header file, I know exactly where to search for / place its implementation. Conversely, if I need to expose the interface of something that was previously hidden in .cpp file (e.g. static function becoming global), I know exactly where to put it.

I've seen too many bad consequences of not following this simple rule. Unnecessary inline functions, breaking any kind of rules about encapsulation, (non)separation of the interface and implementation, misplaced code, to name a few -- all due to the fact that the appropriate sibling header or cpp file was never added.

So: always define both .h and .c files. Make it a standard, follow it, and safely rely on it. Life is much simpler this way, and simplicity is the most important thing in software.

rado