8

this says header files are bad design, but I don't know why. The answers specified there are about the inefficiency of header file when building. Why it is bad design is not really touched upon.

As far as I know:
- headers lets you break the source file up so you can compile smaller things faster
- headers lets you separate the interface from the implementation
- headers lets you specify functionality in only one place. ie. no repeating

Yet using includes, include guards, headers, etc. are considered bad design. How so? What are the alternatives?

-- EDIT: re. DRY issues

A common argument is that it violates DRY in that you repeat changes in signatures in both the .cpp and .h files. However, if the code is designed to reuse functionality specified in outside files, is it not unavoidable that header files must be used?

The question asks why header files are bad design, yet without the headers, is modularity not lost? If modularity is lost, is that not itself a design issue? Thus using header files averts a separate design issue.

Repeating in general is a bad idea, I get that, but it seems unavoidable if you require common functionality. In which case headers are bad, in terms of signature repetition. In terms of how you design your software, I'm inclined to say that splitting code up/modularizing, and reusing code means your code is designed well.

18
  • 6
    it violates DRY in the worst way Mar 24, 2014 at 14:43
  • 1
    This seems to be a duplicate of the question you have linked to. Answers there provide ample explanation of why this is bad design.
    – user82096
    Mar 24, 2014 at 14:54
  • 1
    in terms of inneficiency, the reasons are listed in the link; design-wise, not seeing the answer Mar 24, 2014 at 14:57
  • 1
    I think the inefficiencies are the design problem. The existence of header files doesn't really impact the design of your software - when I'm decomposing requirements to components and then designing those components, the fact that C and C++ use header files and Java and other languages don't doesn't really concern me. The design issue is in the design of the language and its supporting tools (compilers, parsers, IDEs, etc), which is addressed by some answers in that question.
    – Thomas Owens
    Mar 24, 2014 at 15:07
  • 2
    Okay so I write a class. I write a couple of methods, like say Startup(int iCount). And then I discover my class needs something else for this method, say a data structure, like so: Startup(int iCount, void *pS). So I not only need to change the signature of the method in the .c/.cpp file but also in the .h file. I am doing the same work in two different files.
    – Zeroth
    Mar 24, 2014 at 15:41

2 Answers 2

16

This answer looks at header files from a language design perspective. My point is not that you shouldn't use headers in your C or C++ programs – headers are required by these languages. Instead, this answer is an argument that you shouldn't design new languages that use header files.


Header files are bad language design, at least from a modern perspective:

  • Header files in C are a bad design not least because C's macro system is bad: it works via token substitution, not on an AST level. This means:

    • It barfs on circular includes
    • It means that the same stuff is compiled multiple times
    • A seemingly short and simple program might grow to a gigantic behemoth due to a few includes.
    • It is incredibly limited (compared to what the gold standard of macros – Lisp – can do).
  • Header files are bad because they are files. And these files are separate from the actual code. Or not: nobody is preventing you from putting code in the header as well. Why shouldn't the header be in the same file as the source code? There is no solid technical reason for not doing this unless single-pass compilation of each compilation unit is required.

  • Headers are bad because a non-naive compiler can jolly well figure out forward references of symbols without having these be pre-declared. Predeclarations are only useful if a multi-pass compiler is not an option for some reason. Pre-declarations have no value for a human reader (it's a massive DRY violation), and add too little value for a compiler.

And now to refute some possible rebuttals of the “headers are bad” idea:

  • Without headers we can't link against libraries” – I'm sure that's true for C and descendants (which unfortunately are ubiquitous), but this doesn't hold for other languages.

    • A simple alternative is to directly use the source code of a library to extract the interface (this is how many scripting languages like Perl or Python kind of work).

    • This may not be desirable in closed-source environments, where the compiler output could be used to link against (which is roughly how Java works, where .class files contain the interface alongside the executable bytecode).

    The key point is not that no link specification exists, the key is that this specification isn't written by humans.

  • Without headers we can't share things (functions, macros, classes) between files” – yes we can, with things like namespaces and modules containing these things. Let's say I have a #define PI 3.1415 in some C code. To share that definition between my source files, I'd have to #include "my_math_constans.h" or something. Python's solution from math import pi which loads the math module and imports the pi symbol from that module into the current scope works at least just as well.

4
  • 1
    basically your post is "headers are bad because someone types them out, and they're good if generated automatically by the compiler". In no place do you make the case for or against header files themselves :)
    – gbjbaanb
    Mar 24, 2014 at 15:58
  • 2
    @gbjbaanb I do argue against header files: “Header files are bad because they are files. And these files are separate from the actual code. […] Why shouldn't the header be in the same file as the source code? There is no solid technical reason for not doing this”. But you are correct that the main thrust of my argument is against human-generated headers per se.
    – amon
    Mar 24, 2014 at 16:01
  • 3
    fair enough, though at times I wish for a header file - when I see a C# partial class spread over many files with some extension methods added in for good measure. IIRC the C++ committee want to get rid of headers, but I guess they'll have to mandate changes to compilers to emit a binary standard.. which would be a good thing in itself, especially as it means you wouldn't be locked into a proprietary editor and/or compiler.
    – gbjbaanb
    Mar 24, 2014 at 16:08
  • 4
    Oh god, partial classes... they make me want to smack some coders somewhere, usually. All I will say on the matter.
    – Zeroth
    Mar 24, 2014 at 17:09
1

Header files are a legacy of C's heritage - it was written to be close to the hardware, but abstracted enough to run on similar platforms, if a compiler is made for the platform.

What header files do is they define symbols other files can use without the compiler having an issue. The compiler then replaces the symbolic reference with a link or copy of the actual code.

The design issue with this is that you have to repeat yourself. You define the same symbols in two separate files, and when one changes(say a method signature or a class name), the other must be changed as well.

This violates DRY - "Don't Repeat Yourself". This creates an automatic dependency on another file due to the header files. So then when trying to figure out what the objects and classes are doing, you need both, as there's a tonne of syntactical knobs that can turned in either file.

9
  • If you need functionality twice in two different files then, how do you give both the files the same functionality without repeating yourself? Mar 24, 2014 at 15:20
  • @user2738698 You're talking about something entirely different. The header and source files are not repetitions of code. They are repetitions of method signatures.
    – Neil
    Mar 24, 2014 at 15:22
  • 1
    How is this related to your question? You don't give them the same functionality. You asked why header files are bad design, and you've been answered. It sounds like you're actually after something else.
    – Zeroth
    Mar 24, 2014 at 15:26
  • 4
    @user2738698 It's true that you would have to repeat the method's signature in the header, but the logic is in the source file exactly once if you do it right. I don't think that technically qualifies as "repeating yourself". It isn't following DRY in that it is a hassle to have to make corrections in both the source and the header files.
    – Neil
    Mar 24, 2014 at 15:41
  • 4
    @Zeroth oh well, you just made the case against Interfaces, and WSDLs, and IDLs :( I think you might be taking the DRY principle a little too far.
    – gbjbaanb
    Mar 24, 2014 at 16:02

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