24

I find header files to be useful when browsing C++ source files, because they give a "summary" of all the functions and data members in a class. Why do so many other languages (like Ruby, Python, Java, etc.) not have a feature like this? Is this an area where C++'s verbosity comes in handy?

2
  • I'm not familiar with the tools in C and C++, but most IDEs/code editors I've worked in have a "structure" or "outline" view.
    – Michael K
    Commented Mar 24, 2014 at 17:50
  • 1
    Header files are not good - they are necessary! - See also this answer on SO: stackoverflow.com/a/1319570/158483
    – Pete
    Commented Jan 8, 2015 at 17:16

7 Answers 7

38

Original purpose of header files was to allow single-pass compilation and modularity in C. By declaring the methods before they are used, it allowed for only single compilation pass. This age is long time gone thanks to our powerfull computers being able to do multi-pass compilation without any problems, and sometimes even faster than C++ compilers.

C++ being backwards compatible with C needed to keep the header files, but added lot of on top of them, which resulted in quite problematic design. More in FQA.

For modularity, header files were needed as metadata about code in modules. Eg. what methods (and in C++ classes) are available in what library. It was obvious to have developer write this, because compile time was expensive. Nowadays, it is no problem to have compiler generate this metadata from code itself. Java and .NET languages do this normally.

So no. Header files are not good. They were when we still had to have compiler and linker on separate floppies and compilation took 30 minutes. Nowadays, they only get in the way and are sign of bad design.

14
  • 9
    I agree with most of what you write, but the last paragraph makes things a little to simple. Header files still serve a useful purpose for defining public interfaces. Commented Dec 29, 2012 at 15:54
  • 3
    @honk That's what I was getting at with my question. But I think that modern IDEs (as suggested by ElYusubov) kind of negate this. Commented Dec 29, 2012 at 16:13
  • 5
    You could add that the C++ committee is working on Modules which would make C and C++ be able to work without any headers OR with headers used in a more efficient way. That would make this answer more fair.
    – Klaim
    Commented Dec 29, 2012 at 16:46
  • 2
    @MattFichman: Generating some header file is one thing (which most programmer's editors/IDE's can do automatically in some way), but the point about a public API is that it effectively needs to be defined and designed by an actual human. Commented Dec 29, 2012 at 18:46
  • 2
    @honk Yes. But there is no reason for this to be defined in separate files. It can be in same code as implementation. Just like C# is doing it.
    – Euphoric
    Commented Dec 29, 2012 at 20:33
19

While they may be useful for you as a form of documentation, the system surrounding header files is extraordinarily inefficient.

C was designed so that each compilation pass builds a single module; each source file is compiled in a separate run of the compiler. Header files, on the other hand, are injected into that compilation step for each of the source files that reference them.

This means that if your header file is included in 300 source files, then it gets parsed and compiled over and over, 300 separate times while your program is built. The exact same thing with the exact same result, over and over. This is a huge waste of time, and is one of the primary reasons why C and C++ programs take so long to build.

All modern languages intentionally avoid this absurd little inefficiency. Instead, typically in compiled languages the necessary metadata is stored within the build output, allowing the compiled file to act as a sort of quick-lookup reference describing what the compiled file contains. All the benefits of a header file, automatically created with no additional work on your part.

Alternately in interpreted languages, every module that gets loaded stays in memory. Referencing or including or requiring some library will read and compile the associated source code, which stays resident until the program ends. If you also require it elsewhere, no additional work as it's already been loaded.

In either case, you can "browse" the data created by this step using the language's tools. Typically the IDE will have a class browser of some sort. And if the language has a REPL, it can also often be used to generate a documentation summary of any loaded objects.

1
  • 6
    not strictly true - most, if not all, compilers pre-compile the headers as they see them so including them in the next compilation unit is no worse than finding the block of pre-compiled code. Its no different than, say, .NET code repeatedly 'building' system.data.types for every C# file you compile. The reason C/C++ programs take so long is because they are actually compiled (and optimised). All a .NET program needs is to be parsed into IL, the runtime does the actual compilation via JIT. That said, 300 source files in C# code takes quite some time to compile too.
    – gbjbaanb
    Commented Dec 29, 2012 at 18:26
7

It is not clear on, what you mean by browsing file for functions and data members. However, most IDE's do provide Tools to browse the class and see class data members.

For example: Visual Studio has Class View and Object browser that nicely provides your requested functionality. Like in the following screen-shots.

enter image description here

enter image description here

5

An additional disadvantage of header files is that the program depends on the order of their inclusion, and the programmer has to take extra steps to ensure correctness.

That, coupled with C's macro system (inherited by C++), leads to many pitfalls and confusing situations.

To illustrate, if one header defined some symbol using macros for its use, and another header used the symbol in another fashion such as a name for a function, then the order of inclusion would greatly influence the final result. There are many such examples.

2

I always liked header files as they provide a form of interface to the implementation, along with some extra information such as class variables, all in one easy-to-view file.

I see a lot of C# code (that doesn't need 2 files per class) written using 2 files per class - one the actual class implementation, and another with an interface in it. This design is good for mocking (essential in some systems) and helps to define the documentation of the class without having to use the IDE to view the compiled metadata. I'd go so far to say its good practice.

So C/C++ mandating an equivalent (of sorts) of an interface in header files is a good thing.

I know there are proponents of other systems that do not like them for reasons including 'its more difficult to just hack out code if you have to put things in 2 files', but my attitude is that just hacking out code is not good practice anyway, and once you start writing/designing code with a bit more thought, then you'll be defining headers/interfaces as a matter of course.

5
  • Interface and Implementation in different files? If you need this by design this is still very common to define the interface (or abstract class) in languages such as Java/C# in one file and hide the implementation(s) in other files. This does not require old and tricky header files. Commented Dec 30, 2012 at 14:49
  • eh? isn't that what I said - you define the interface and the class implementation in 2 files.
    – gbjbaanb
    Commented Dec 31, 2012 at 0:30
  • 2
    well, that does not require header files and that does not make header files any better. Yes, they are needed in languages with a legacy, but as a concept they are not needed to split interface/implementation in different files (actually, they make it worse). Commented Jan 1, 2013 at 12:54
  • @Petter I think you misunderstand, conceptually they are no different - a header exists to provide an interface in the C language, and though you are right - you can combine the 2 (as many do with header-only C code) its not a best practice that I've seen followed in many places. All C# devs I've seen split the interface away from the class, for example. Its a good practice to do this as then you can include the interface file in multiple other files without pollution. Now, if you think that this split is a best practice (it is) then the way to achieve it in C is by using header files.
    – gbjbaanb
    Commented Mar 24, 2014 at 15:55
  • If headers were actually useful for separating interface and implementation, things like PImpl wouldn't be needed to hide private components and decouple end-users from having to recompile against them. Instead, we get the worst of both worlds. Headers feign a quickly dismissed facade of separation, while opening a myriad of pitfalls, which require verbose boilerplate code if you need to work around them. Commented Sep 20, 2015 at 22:16
1

I would actually say that headers files are not great because they muddy the interface and implementation. The intent with programming in general, and especially OOP is to have a defined interface and hide the implementation details, but a C++ header file shows you both the methods, inheritance, and the public members (interface) as well as private methods and private members (some part of the implementation). Not to mention that in some cases you end up inlining code or constructors in the header file, and some libraries include template code in the headers, which really mixes implementation with interface.

The original intent, I believe, was to make it possible for code to use other libraries, objects, etc without having to import the entire contents of the script. All you need is the header to compile and link. It saves time and cycles that way. In that instance, it's a decent idea, but it's just one way of solving these issues.

As for browsing the structure of the program, most IDEs provide that ability, and there are a lot of tools that will kick out the interfaces, do code analysis, decompilation, etc so you can see what's happening under the covers.

As for why other languages don't implement the same feature? Well, because other languages come from other people, and those designers/creators have a different vision of how things should work.

The best answer is to stick with what does the job you need to do, and makes you happy.

1

In many programming languages, when a program is subdivided into multiple compilation units, code in one unit will only be able to use things defined in another if the compiler has some means of knowing what those things are. Rather than requiring that a compiler processing one compilation unit examine the entire text of every compilation unit which defines anything used within the present unit, it's best to have the compiler receive, while processing each unit, the full text of the unit to be compiled along with a little information from all of the others.

In C, the programmer is responsible for creating two files for each unit--one containing information which will only be needed when compiling that unit, and one containing information which will also be needed when compiling other units. This is a rather nasty, hacky, design, but it avoids the need to have a language standard specify anything about how compilers should generate and process any intermediate files. Many other languages use a different approach, wherein a compiler will generate from each source file an intermediate file describing everything in that source file which is supposed to be accessible to outside code. This approach avoids the need to have duplicate information in two source files, but it requires that a compilation platform have defined file semantics in a way that is not required for C.

Not the answer you're looking for? Browse other questions tagged or ask your own question.