I'm working on a codebase that is known to only run on windows and be compiled under Visual Studio (it integrates tightly with excel so it's not going anywhere). I'm wondering if I should go with the traditional include guards or use #pragma once
for our code. I would think letting the compiler deal with #pragma once
will yield faster compiles and is less error prone when copying and pasting. It is also slightly less ugly ;)
Note: to get the faster compile times we could use Redundant Include Guards but that adds a tight coupling between the included file and the including file. Usually it's ok because the guard should be based on the file name and would only change if you needed to change in the include name anyways.
If you're positive that you will never use this code in a compiler that doesn't support it (Windows/VS, GCC, and Clang are examples of compilers that do support it), then you can certainly use #pragma once without worries.
You can also just use both (see example below), so that you get portability and compilation speedup on compatible systems
I don't think it will make a significant difference in compile time but
#pragma once
is very well supported across compilers but not actually part of the standard. The preprocessor may be a little faster with it as it is more simple to understand your exact intent.#pragma once
is less prone to making mistakes and it is less code to type.To speed up compile time more just forward declare instead of including in .h files when you can.
I prefer to use
#pragma once
.See this wikipedia article about the possibility of using both.
There's an related question to which I answered:
I'm adding the answer here too in case someone stumbles over this question and not the other.
Atop explanation by Konrad Kleine above.
A brief summary:
# pragma once
it is much of the compiler responsibility, not to allow its inclusion more than once. Which means, after you mention the code-snippet in the file, it is no more your responsibility.Now, compiler looks, for this code-snippet at the beginning of the file, and skips it from being included (if already included once). This definitely will reduce the compilation-time (on an average and in huge-system). However, in case of mocks/test environment, will make the test-cases implementation difficult, due to circular etc dependencies.
#ifndef XYZ_H
for the headers, it is more of the developers responsibility to maintain the dependency of headers. Which means, whenever due to some new header file, there is possibility of the circular dependency, compiler will just flag some "undefined ..
" error messages at compile time, and it is user to check the logical connection/flow of the entities and rectify the improper includes.This definitely will add to the compilation time (as needs to rectified and re-run). Also, as it works on the basis of including the file, based on the "XYZ_H" defined-state, and still complains, if not able to get all the definitions.
Therefore, to avoid situations like this, we should use, as;
i.e. the combination of both.
After engaging in an extended discussion about the supposed performance tradeoff between
#pragma once
and#ifndef
guards vs. the argument of correctness or not (I was taking the side of#pragma once
based on some relatively recent indoctrination to that end), I decided to finally test the theory that#pragma once
is faster because the compiler doesn't have to try to re-#include
a file that had already been included.For the test, I automatically generated 500 header files with complex interdependencies, and had a
.c
file that#include
s them all. I ran the test three ways, once with just#ifndef
, once with just#pragma once
, and once with both. I performed the test on a fairly modern system (a 2014 MacBook Pro running OSX, using XCode's bundled Clang, with the internal SSD).First, the test code:
And now, my various test runs:
As you can see, the versions with
#pragma once
were indeed slightly faster to preprocess than the#ifndef
-only one, but the difference was quite negligible, and would be far overshadowed by the amount of time that actually building and linking the code would take. Perhaps with a large enough codebase it might actually lead to a difference in build times of a few seconds, but between modern compilers being able to optimize#ifndef
guards, the fact that OSes have good disk caches, and the increasing speeds of storage technology, it seems that the performance argument is moot, at least on a typical developer system in this day and age. Older and more exotic build environments (e.g. headers hosted on a network share, building from tape, etc.) may change the equation somewhat but in those circumstances it seems more useful to simply make a less fragile build environment in the first place.The fact of the matter is,
#ifndef
is standardized with standard behavior whereas#pragma once
is not, and#ifndef
also handles weird filesystem and search path corner cases whereas#pragma once
can get very confused by certain things, leading to incorrect behavior which the programmer has no control over. The main problem with#ifndef
is programmers choosing bad names for their guards (with name collisions and so on) and even then it's quite possible for the consumer of an API to override those poor names using#undef
- not a perfect solution, perhaps, but it's possible, whereas#pragma once
has no recourse if the compiler is erroneously culling an#include
.Thus, even though
#pragma once
is demonstrably (slightly) faster, I don't agree that this in and of itself is a reason to use it over#ifndef
guards.EDIT: Thanks to feedback from @LightnessRacesInOrbit I've increased the number of header files and changed the test to only run the preprocessor step, eliminating whatever small amount of time was being added in by the compile and link process (which was trivial before and nonexistent now). As expected, the differential is about the same.
I think the first thing you should do is check to see if this is really going to make a difference, ie. you should first test the performance. One of the searches in google threw up this.
In the results page, the columns are sligthly off for me, but it's clear that at least up to VC6 microsoft was not implementing the include guard optimisations that the other tools were using. Where the include guard was internal it took 50 times as long compared with where the include guard was external (external include guards are at least as good as #pragma). But let's consider the possible affect of this:
According to the tables presented, the time to open the include and check it is 50 times that of a #pragma equivalent. But the actual time to do so was measured at 1 microsecond per file back in 1999!
So, how many duplicate headers will a single TU have? This depends on your style, but if we say that an average TU has 100 duplicates then in 1999 we're potentially paying 100 microseconds per TU. With HDD improvements this is probably significantly lower by now, but even then with precompiled headers and correct dependency tracking the total cumulative cost of this for a project is almost certainly an insigificant part of your build time.
Now, on the flip side, as unlikely as it may be, if you ever move to a compiler that doesn't support
#pragma once
then consider how much time will it take to update your entire source base to have include guards rather than #pragma?There is no reason that Microsoft could not implement an include guard optimisation in the same way that GCC and every other compiler does (actually can anybody confirm if their more recent versions implement this?). IMHO,
#pragma once
does very little other than limit your choice of alternative compiler.