Day 11 - Include file header guard

I see an issue with the include file header guards. The implementation
1
2
3
4
5
6
#if !defined(FILE_NAME)

//...

#define FILE_NAME
#endif
The purpose of the header guard is to prevent multiple includes of a header file. However, similar to the "unity" method of the cpp files, header files themselves may include other header files and so on and so on. If one of those files happens to include FILE_NAME.h then the header guard will fail because the define doesn't occur until the end of the file.

I most often see the #define immediately after the check
1
2
3
4
#ifndef FILE_NAME
#define FILE_NAME
//...
#endif


- tim
Nowadays it is simpler to put only this at beginning of header:
1
#pragma once

While it was not supported for older compilers, all modern C/C++ compilers (MSVC, Clang, GCC) supports that for at least 10 years or more.
Well...I'm the visiting team at this game.
Casey's park, his rules.
I don't want to introduce something unless there's a need.
I don't _know_ how portable pragmas are.
YMMV

- tim
Well, truth be told, we actually don't need those in Handmade Hero at all, since we control the translation unit specifically. So they could all be removed entirely.

The reason why they're still automatically added by my Emacs config, rather than #pragma once, is because even to this day, AFAIK, at least one compiler is significantly slower using #pragma once than using redundant include guards - meaning include guards used at the site of the include, rather than in the file being included.

- Casey
I was looking at CDep tool at MollyRocket and I saw in the code macro guard at include site like this:

1
2
3
#if !defined(CDEP_HEADER_H)
#include "cdep_header.h"
#endif


Was that also for speed?
yes. The theory is that the compiler will save time by not opening the file and then detecting the guard. In the old days, opening files was a visual event that triggered flashing lights and such, so this was a measurable improvement.

today, the savings are still there but at a far lower percent improvement. There is a compiler switch you can throw to see all the files being opened in a compile; warning: it vast so do it for a single file only.

Finally, the code comprehension goes down significantly when there are many pre-processor commands that are just guarding headers. Best practice is to avoid this unless demanded and then reluctantly.

note: MSVC IDE has a setting to show build times.

- tim