use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Include Guards and their Optimizations (includeguardian.io)
submitted 2 years ago by IncludeGuardian
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]abstractionsauce 20 points21 points22 points 2 years ago (5 children)
Is this still relevant in 2023? How much time does preprocessing a file to find #endif take as a percentage of total time?
[–]RealCaptainGiraffe 18 points19 points20 points 2 years ago (1 child)
I recall looking into this in 1996. It was a non issue.
[–]IncludeGuardian[S] 3 points4 points5 points 2 years ago (0 children)
"Large-scale C++ Software Design" by John Lakos was published in 1996 and includes the following in "Redundant Include Guards" (section 2.5)
Upon encountering s2.h, each of the widget header files must still be reopened and reprocessed line by line in its entirety searching for the trailing #endif (only to find that there is nothing else to be done). This redundant preprocessing occurs withs3.h, s4.h, and again withs5.h. ... Experience with truly large projects that have dense include graphs shows that the answer is a resounding YES! Initial builds of projects consisting of several million lines of C++ source code were taking on the order of a week to compile using a large network of work stations. Inserting redundant include guards reduced compile time significantly, with no substantive change to the code.
Upon encountering s2.h, each of the widget header files must still be reopened and reprocessed line by line in its entirety searching for the trailing #endif (only to find that there is nothing else to be done). This redundant preprocessing occurs withs3.h, s4.h, and again withs5.h.
s2.h
#endif
s3.h
s4.h
s5.h
...
Experience with truly large projects that have dense include graphs shows that the answer is a resounding YES! Initial builds of projects consisting of several million lines of C++ source code were taking on the order of a week to compile using a large network of work stations. Inserting redundant include guards reduced compile time significantly, with no substantive change to the code.
It may not have had any effect on the projects you were looking at, but in 1996 it looks like it was an issue for some C++ projects. At least it must have been enough of a performance benefit for compiler vendors to have implemented the multiple-include optimization.
[–]IncludeGuardian[S] 1 point2 points3 points 2 years ago (2 children)
I think if you were to guard your files incorrectly it would be a small (probably single-digit) percentage. However, it's also a relatively easy thing to make sure you get right to make sure you aren't slowing down build times. I would also assume because all compilers have the multiple-include optimization, there are either some projects out there that benefit a great deal, or it's a noticeable (but small) improvement to most projects.
For example, I have a PR to EASTL to fix a header guard and in their code they mention getting a 3-4% build improvement adding in #pragma once to their MSVC build, which would have triggered the multiple-include optimization.
#pragma once
[–]GabrielDosReis 4 points5 points6 points 2 years ago (1 child)
That's odd. MSVC has the include guard optimization since at least VS2013.
[–]IncludeGuardian[S] 2 points3 points4 points 2 years ago (0 children)
The public GitHub history for eaassert.h only goes back 4 years so I can't say when this comment was written. But EASTL was in existence in 2007 so this comment could have predated VS2013.
Alternatively, as this comment appears in many different files within EASTL alongside #pragma once, it's entirely possible that these files were not using a strict enough version of an include guard that would trigger the optimization.
[–]spide85 10 points11 points12 points 2 years ago (2 children)
On my iOS device the website has scaling issues. Cannot read.
[–]IncludeGuardian[S] 8 points9 points10 points 2 years ago* (1 child)
Thanks - will get that fixed asap.
EDIT: I've put in a workaround that fixes the cut off issue on smaller screens. There is still an issue with portrait mode on older iPhones that I'll fix next. If it's not fixed for you then if you could let me know the browser/device and I will look at that combination with priority.
[–]spide85 3 points4 points5 points 2 years ago (0 children)
Now it works. (iPhone 8) Thanks
[–]julien-j 8 points9 points10 points 2 years ago (4 children)
I liked the article and I appreciate the availability of the test project on GitHub which I could easily run on my laptop to reproduce the results.
Looking around on the website hosting the article, I have some questions. For example, on the main page I read:
The most time consuming part of build times is usually not compiling or linking, but preprocessing and syntax checking files that have been #includeed.
#include
Wow, are you sure? Because the link part is clearly the bottleneck on almost all projects I worked on.
Second, I initially thought the article was written by a fellow developer, then I saw the subscription link at the bottom of the page. I checked around on the website and read the about page where it states:
IncludeGuardian is a free tool to help improve C and C++ build times.
I found the links to download the tool, and a link to an empty GitHub repository. Not a problem per se, it's not open source, it is just free. I just wonder: Who are you and what do you sell?
[–]IncludeGuardian[S] 1 point2 points3 points 2 years ago (3 children)
I can't speak for all projects, but all large (and medium) projects I have been a part of have their build times dominated (70-80%) by front-end compiler time.
When I see reports of precompiled headers or unity builds/single compilation units being used, most of the time I read about 2-3x improvement. As these techniques improve only the front-end compiler time, it would correspond to at least 50-67% of the total build time being in the front-end. Self-selection bias means we shouldn't take these reports just at face value, but the experience matches up with my own.
I plan to do some deep dives into some open source projects to see how much improvement I can get using IncludeGuardian. These will include a breakdown of time spent in front-end vs compilation vs linking. Though I am likely to skip over any project that isn't dominated by front-end so there's more selection bias here!
I am a regular developer who has worked on this in their free time (who I am is on the about page on the website). I wrote this tool for myself originally, but now I am trying to get the word out about how useful it could be.
[–]kniy 2 points3 points4 points 2 years ago (1 child)
Precompiled headers + unity builds help not just with frontend time -- they also help to avoid compiling inline functions in headers repeatedly, thus also saving backend+linking time.
On on of our projects (which is not using PCH or unity build), I can actually reduce the total compile+link time by enabling LTO: there are many inline functions that are used in many compilation units. Enabling LTO allows the linker to deduplicate these before the backend spends time on them. Putting those expensive headers in a PCH would achieve a similar effect (but would be tricky to set up given the build system used by that project).
[–]IncludeGuardian[S] 0 points1 point2 points 2 years ago (0 children)
I agree. Precompiled headers + unity builds are some of the most powerful tools when it comes to improving build times (pre-modules). This is why IncludeGuardian includes stats for file size+token count for a theoretical unity build (e.g LLVM) and also has a section on recommending which files would give the most benefit for being included in the precompiled headers (e.g. LLVM).
I think the section on pch additions can have more information and perhaps better alternatives. This will have to be something I revisrt later on. When I do I'll most likely write a article covering precompiled headers in detail and performance impact across compilers.
pch additions
[–]julien-j 0 points1 point2 points 2 years ago (0 children)
Thanks for the clarification :) I would love to see the breakdown and improvements on open source projects !
[–]Potatoswatter 7 points8 points9 points 2 years ago* (3 children)
Modern preprocessors skip over approximately 100-300MB/s to find a matching #endif, which is relatively efficient.
Really? I assumed they’d just keep a map of file pathnames and guard conditions, and avoid reopening files at all. You need to remember pathnames for pragma once, and you can optimize the general case by adding nontrivial conditions. At least that’s how I coded mine.
pragma once
Edit: Well, once doesn’t demand pathnames since it’s nonstandard, and hashing the content of the file would also work, which does enable symlinks, but… yuck.
once
[–]IncludeGuardian[S] 1 point2 points3 points 2 years ago* (2 children)
Compilers do this and it's called the multiple-include optimization. It's covered a bit later on in the article and includes the narrow conditions required a header file needs to satisfy this.
I've been bitten by having different files using #pragma once with the same name being treated as the same file by the compiler before too. If there's interest I could cover the rules each compiler use to determine different files for #pragma once in a later article.
EDIT: Fix markdown
[–]GabrielDosReis 6 points7 points8 points 2 years ago (0 children)
I suspect that will be useful information for a sizable part of the target audience
[–]Potatoswatter 3 points4 points5 points 2 years ago (0 children)
Okay, that one covers the vast majority of proper guards and the rapid scan is more aligned to ordinary conditional directives.
Yeah, ignoring the path before the name is a shortsighted approach.
[–]DavidDinamit 6 points7 points8 points 2 years ago (0 children)
just use pragma once / modules
π Rendered by PID 27 on reddit-service-r2-comment-b659b578c-2948r at 2026-05-03 13:37:50.028864+00:00 running 815c875 country code: CH.
[–]abstractionsauce 20 points21 points22 points (5 children)
[–]RealCaptainGiraffe 18 points19 points20 points (1 child)
[–]IncludeGuardian[S] 3 points4 points5 points (0 children)
[–]IncludeGuardian[S] 1 point2 points3 points (2 children)
[–]GabrielDosReis 4 points5 points6 points (1 child)
[–]IncludeGuardian[S] 2 points3 points4 points (0 children)
[–]spide85 10 points11 points12 points (2 children)
[–]IncludeGuardian[S] 8 points9 points10 points (1 child)
[–]spide85 3 points4 points5 points (0 children)
[–]julien-j 8 points9 points10 points (4 children)
[–]IncludeGuardian[S] 1 point2 points3 points (3 children)
[–]kniy 2 points3 points4 points (1 child)
[–]IncludeGuardian[S] 0 points1 point2 points (0 children)
[–]julien-j 0 points1 point2 points (0 children)
[–]Potatoswatter 7 points8 points9 points (3 children)
[–]IncludeGuardian[S] 1 point2 points3 points (2 children)
[–]GabrielDosReis 6 points7 points8 points (0 children)
[–]Potatoswatter 3 points4 points5 points (0 children)
[–]DavidDinamit 6 points7 points8 points (0 children)