Header Files, Compilers, and Static Type Checks

Have you ever thought to yourself, “why does C++ have header files”?  I had never thought about it much until recently and decided to do some research into why some languages (C, C++, Objective C etc.) use header files but other languages do not (e.g. C# and Java).

Header files, in case you do not have much experience with them, are where you put declarations and definitions.  You declare constants, function signatures, type definitions (like structs) etc.  In C, all these declarations go into a .h file and then you put the implementation of your functions in .c files.

Here’s an example of a header file called mainproj.h:

#ifndef MAINPROJ_H__
#define MAINPROJ_H__

extern const char const *one_hit_wonder;

void MyFN( int left, int back, int right );

Here is a corresponding source file mainproj.c:

#include "mainproj.h"

const char const *one_hit_wonder = "Yazz";

void MyFN( int left, int back, int right )
    printf( "The only way is up, baby\n" );

Notice that the header only has the function definition for MyFN and it also does not specify what one_hit_wonder is set to. But why do we do this in C but not in Java?  Both are compiled and statically typed.  Ask GOOGLE!

A great MSDN blog post by Eric Lippert called “How Many Passes” was very helpful.  The main idea I got out of the article is that header files are necessary because of Static Typing.  To enforce type checks, the compiler needs to know things like function signatures to guarantee functions never get called with the wrong argument types.

Eric lists two reasons for header files:

  1. Compilers can be designed to do a single pass over the source code instead of multiple passes.
  2. Programmers can compile a single source file instead of all the files.

Single Pass Compilation

In a language like C#, which is statically typed but has no header files, the compiler needs to run over all the source code once to collect declarations and function signatures and then a second time to actually compile the function bodies (where all the real work of a program happens) using the declarations it knows about to do type checks.

It makes sense to me that C and C++ would have header files because they are quite old languages and the CPU and Memory resources required to do multiple passes in this way would be very expensive on computers of that era.  Nowadays, computers have more resources and the process is less of a problem.

Single file compilation

One interesting other benefit of header files though is that a programmer can compile a single file.  Java and C# can not do that: compilation occurs at the project level, not the file level.  So if a single file is changed, all files must be re-compiled.  That makes sense because the compiler needs to check every file in order to get the declarations.  In languages with header files, you can only compile the file that changed because you have header files to guarantee type checks between files.

Relevance Today

Interesting as this may be, is it relevant today if you only do Java, C#, or a dynamic language?  Actually it does!

For instance, consider TypeScript and Flow which both bring gradual typing to JavaScript. Both systems have a concept of Declaration files.  What do they do?  You guessed it!  Type declarations, function signatures, etc.

TypeScript Declaration file:

module Zoo {
  function fooFn(bar: string): void;

Flow Declaration file:

declare module Zoo {
  declare function fooFn(bar: string): void;

To me, these look an awful lot like header files!

As we see, header files are not dead!  They are alive and well in many strategies for Type Checking.

Header Files, Compilers, and Static Type Checks

Understand Agile by Understanding How It’s Not Waterfall


Many engineers and managers have a really hard time with the Agile project management methodology (the “new way” of building things). They desperately want to have Agile projects, but implementing the methodology is a struggle. One way that I have found to be useful in understanding and implementing Agile is by doing a compare and contrast with the Waterfall methodology (the “old way” of building things).

However, most people do not understand the Waterfall methodology; the very thing that Agile is attempting to fix in order to make developing software more effective and manageable. If you do not understand what the ineffective way is, how can you successfully avoid it?

The Waterfall Straw Man

A common symptom of misunderstanding Waterfall is the ritual building and burning of the Waterfall Straw Man. If you work in software long enough, you will hear all about the Waterfall Straw Man. You’ll hear a collection of arguments about how some action/process/etc. is bad because it is “too waterfall”!

  • We can’t predict the end date; that’s waterfall.
  • We can’t plan out all the features or tasks; that’s waterfall.
  • We can’t have meetings; that’s waterfall.
  • We can’t make document; that’s waterfall.

Waterfall becomes the culmination of every ridiculous or bad practice we’ve experienced or heard about in a software project. It’s the boogeyman of managing software projects. On some teams even the accusation of “waterfall” is enough to kill any process.

The Facts about Waterfall

What is Waterfall really? The funny thing is that Waterfall is actually a very successful project management method throughout the world in manufacturing and construction. The following is the simplified waterfall approach:

  1. Identify a Project
  2. Plan the project
  3. Implement the Plan
  4. Deliver Tangible Output to the Customer

That’s it! That is waterfall! It actually has several benefits. One is that comprehensive planning up front allows effective resource planning. Also, discovering and fixing problems early on is less costly than dealing with them later. You might argue,

“Well obviously the problem is that Waterfall is not Customer centric.”

Wrong. Including the customer in the planning of a waterfall project is not uncommon. You might instead say something like the following,

“Well obviously the problem is that Waterfall doesn’t have Sprints/Standup Meetings/Backlogs/etc. !”

And you would be wrong. Waterfall can have any of those things. Those processes and components are popular in but not specific to Agile.

The Waterfall method successfully builds furniture, cars, bridges, and skyscrapers every day throughout the world. Sometimes, a customer is unhappy with the result but Waterfall gets it right many times.

The Case for Agile

So then, why use Agile if Waterfall is so great? Waterfall is very poor at managing change; which we have learned is exceptionally common in software development (nobody really knows why). A central tenet of Waterfall is that plans are made upfront, complete, and comprehensive. Changing a plan later is rare and exceptionally costly because a waterfall plan is so large scale.

You can read the Agile Manifesto to see what the creators intend Agile to be. Knowing their intent, I suggest these three, concrete improvements that Agile makes to Waterfall:

  1. Iterative Processes
  2. Frequent Delivery of Tangible Output

The Agile method would be applied in this manner:

    1. Identify a project.
    2. Plan what you know as best you can; Include the customer in the planning.
    3. Execute the project plan to deliver some tangible output to the customer quickly for validation.
    4. Discover new information from (a) your development and (b) the customer upon your delivery.

… Iterate over steps 2-4 until the desired output is delivered.

Wait! All that planning sounds an awful lot like Waterfall. Of course it does! Making plans was never the problem with Waterfall. Inability to change plans based on new information is the problem with Waterfall.

Scrum, Kanban, Xtreme Programming, and other Agile methodologies have a lot of additional behaviors and processes, but they are all built on this frame: (1) Iterative process and (2) frequent delivery of tangible output.


Do not fall into the trap of burning the Waterfall Straw Man. It benefits no one. In fact, I have seen some software teams implement Agile so poorly that they run into more problems than if they just implemented a straightforward Waterfall plan. At least then they would have planned before coding, interacted with the customer at least once, and worked to deliver what they promised in their plan. Better than nothing!

Agile is absolutely the way to go when building Software. It also works in other projects where change management is important (which is a surprising number of projects). Take the time to understand Project Management so that you can benefit from these proven practices.

Understand Agile by Understanding How It’s Not Waterfall