In the world of C/C++, we use headers extensively. The basic rule is that C/CPP files contain code that becomes binaries, and H files contain the interfaces that allow us to reference them in other C files. Any program more complex than a calculator will likely contain multiple C files that are combined into one massive binary.
There are a few quick tricks that can make your headers quicker to generate and more reliable.
1. Link it once
Most compilers struggle with multiple references to the same header, because it basically stacks all the symbols up. When those symbols are the same (i.e. you pulled from the same header twice), you basically guarantee these collision problems.
If you’ve ever looked at the standard headers, you might have noticed something like this:
#ifndef THIS_HEADER_H #define HEADER_H //All the contents #endif
This pattern ensures that the precompiler doesn’t encounter collisions for one simple reason:
Every time the header is called, the precompiler checks whether the symbols have already been defined. If it’s already got that symbol (because it already pulled that header in), it will skip trying to pull the symbols in again.
This pattern is trememdously useful, and can be tweaked for a bunch of applications.
2. Copy the C
If you’re using something like Doxygen to document your code, you probably cringe a bit at the idea of copying your c files directly into the headers. For one thing, headers shouldn’t have any binaries, and for another you don’t want to lose any documentation you already wrote into the header.
But, if you already have the documentation in the original c files (which I recommend – it costs nothing and saves everyone time), you’re down to one problem.
One of the key concerns about generating headers is that the header interface needs to match the actual binary. The best way to ensure that they match is to copy the originals directly to the headers – a copy should always match the original.
Now we have headers that are full of not-header content. Fortunately, most of the not-header content is wrapped inside of brackets. With VI, you can quickly fix it with the following sequence:
That pattern seeks every open bracket, deletes everything between it and the next bracket (and the brackets themselves), and inserts a semicolon. This lets you quickly extract all the compilable code from the header and format it like a header. Simplicity itself.
Note that, for this pattern to work properly, you will need to store all your static constant data and structure definitions in their own headers. This is already a fairly common practice among programmers, and it makes generating and maintaining headers much faster and more convenient, so the cost is minimal.
These are just two simple techniques for simplifying your documentation and header construction. If you have another pattern that you find useful, post it in the comments below.