#pragma once vs.
After getting 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
#includes 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
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
Before commenting, please read the comment policy.
Avatars provided via Libravatar