3

I used to use the following code to make sure that the include file is not loaded more than once.

#ifndef _STRING_
#include <string>
#endif

// use std::string here
std::string str;
...

This trick is illustrated in the book "API Design for C++".

Now my co-work told me that this is not necessary in Visual Studio because if the implementation head file of string contains #pragma once, the include guard is not required to improve the compilation speed.

Is that correct?

Quote from original book:

7.2.3 Redundant #include Guards
Another way to reduce the overhead of parsing too many include files is to add redundant preprocessor
guards at the point of inclusion. For example, if you have an include file, bigfile.h, that looks
like this
#ifndef BIGFILE_H
#define BIGFILE_H
// lots and lots of code
#endif
then you might include this file from another header by doing the following:
#ifndef BIGFILE_H
#include "bigfile.h"
#endif
This saves the cost of pointlessly opening and parsing the entire include file if you’ve already
included it.
q0987
  • 34,938
  • 69
  • 242
  • 387
  • http://compgroups.net/comp.lang.c++.moderated/sutters-guidelines-and-redundant-incl/18725 – q0987 Feb 27 '13 at 18:59
  • http://books.google.com/books?id=mmjVIC6WolgC&pg=PT18&lpg=PT18&dq=Always+write+internal+%23include+guards.+Never+write+external+%23include+guards&source=bl&ots=ccUmMSdLTa&sig=RSuH_-06Em9V02D94PTQULL_m3U&hl=en&sa=X&ei=01cuUau1OYTy2QWnzoGgCQ&ved=0CGgQ6AEwCA – q0987 Feb 27 '13 at 19:02
  • Usage of `#pragma once` will provoke the same optimization by all major compilers. I recommend its use. Many compilers (at least gcc and vs) implement the same optimization with standard internal include guards. I hope that was an old book you were reading. Redundant external guards haven't given any benefit to users of major compilers for years. – John Aug 07 '17 at 19:32

5 Answers5

5

Usually the term 'include guard' means that this #ifdef,#define,#endif sequence is put around the contents of a particular header file inside this file.

A number of C++ compilers provide the #pragma once statement that guarantees the same behavior externally. But I would discourage using it for sake of portable C/C++ code.

UPDATE (according the OP's edit)
Additionally putting the #ifdef,#endif around the #include statement in another file might prevent the preprocessor from opening the include file itself (and thus reducing compile time and memory usage slightly). I'd expect#pragma once would do this automatically, but can't tell for sure (this might be implementation specific).

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 1
    This is exact what I feel the book author tries to convey! – q0987 Feb 27 '13 at 18:47
  • 2
    @q0987 But this behavior might be specific for compiler implementation though. I'd expect a well implemented preprocessor to cache the already opened and parsed include files somehow, thus making this trick irrelevant ... – πάντα ῥεῖ Feb 27 '13 at 18:54
2

You don't ever need to do that because any header file written by a competent developer will have its own guard. You can assume the standard library headers were written by competent engineers, and if you ever find yourself using a third party header without include guards... well, that third party is now highly suspect...

As for writing your own headers, you can use the standard:

#ifndef MY_HEADER_H
#define MY_HEADER_H

// ...code

#endif

Or just use:

#pragma once

Note that this is not standard C or C++, it is a compiler extension. It won't work on every compiler out there, but using it is your decision and depends on your expected use.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • I think we are talking about two different things. My question is whether we should use include guard when we use a pre-existing head file that has either #pragma once or #ifndef xxx – q0987 Feb 27 '13 at 18:17
  • @q0987: We're not talking about different things. The code you have shown is *not* how you use include guards and is completely unnecessary. You need to understand that, if a header contains an include guard (which they all will), it can *never* be included twice. That is why your approach is wrong. Your book is just flat wrong. Either you are misunderstanding it or it is a bad book. – Ed S. Feb 27 '13 at 18:18
  • 1
    @q0987: No. Your book is just wrong. Since the header already has an include guard it will never be included twice. Heck, the author himself says it is redundant! How can something which is redundant be helpful in any way? By definition it does nothing at all. – Ed S. Feb 27 '13 at 18:22
  • @g-makulik: Heh, I just added ab blurb about that. I don't typically use it. – Ed S. Feb 27 '13 at 18:23
  • @q0987: You should look for a new book. Check out [this thread](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Ed S. Feb 27 '13 at 18:25
  • The book is one of the highly rated C++ programming books. – q0987 Feb 27 '13 at 18:27
  • Redundant is always good in many industrial devices. for example airplane. I still think we are talking about two different things. – q0987 Feb 27 '13 at 18:30
  • 1
    @q0987: Yes, we are; you're describing redundant systems in the anticipation of a failure. That is not this. I don't know where your numbers came from, but I will say it again; *the book is wrong*. I don't care what it is "rated". Do you understand the claimed performance benefit? Why do you think that checking a constant in location A is any faster than doing so in location B? You asked the question, this is my answer. The only thing I can think of is it may prevent the file from being read from disk, but it may also be cached already. – Ed S. Feb 27 '13 at 18:35
  • 1
    @q0987: I can tell you that, in ~10 years of writing production C and C++ code, I have *never* seen that idiom used. Ever. – Ed S. Feb 27 '13 at 18:37
  • I've seen it used before, and if I remember correctly it was mentioned in the Lakos book. I've been told it did make a difference years ago, but I'm not sure it does anymore. It's fragile to keep in sync, and compilers are much smarter about reparsing files with internal include guards now. As with anything, the only way to know if it will benefit you is to try it and profile. – Retired Ninja Feb 27 '13 at 18:51
  • @RetiredNinja: Yeah, I was thinking the same thing. You have to duplicate the header's include guard and hope it never changes. – Ed S. Feb 27 '13 at 19:12
  • There is a difference between including a header twice, and parsing it twice. This idiom tries to avoid parsing twice (or more). On big systems, it was making a difference. Not sure with todays compilers. – Korchkidu Jul 10 '13 at 18:32
2

Redundant include guards are, by definition "redundant". They do not affect the binaries created through compilation. However, they do have a benefit. Redundant include guards can reduce compile times.

Who cares about compile times? I care. I am just one developer is a project of hundreds of developers with millions of lines of source code in thousands of source files. A complete rebuild of the project takes me 45 minutes. Incremental builds from revision control pulls take me 20+ minutes. As my work depends on this big project, I cannot perform any testing while waiting on this prolonged build. If that build time were cut to under 5 minutes, our company would benefit greatly. Suppose the build time saving was 20 minutes. 1 year * 100 developers * 1 build/day, * 1/3 hour/build * 250 days/year * $50/hr = $416,667 savings per year. Someone should care about that.

For Ed S, I have been using Redundant Include guards for 10 years. Occasionally you will find someone who uses the technique, but most shy from it because it can make ugly-looking code. "#pragma once" surely looks a lot cleaner. Percentage-wise, very few developers continually try to improve their talent by continuing their education and techniques. The redundant #include guards technique is a bit obscure, and its benefits are only realized when someone bothers to do an analysis on large-scale projects. How many develops do you know who go out of their way to buy C++ books on advanced techniques?

Back to the original question about Redundant Include guards vs #pragma once in Visual Studio... According to the Wiki #pragma once, compilers which support "#pragma once" potentially can be more efficient that #include guards as they can analyze file names and path to prevent loading of files which were already loaded. Three compilers were mentioned by name as having this optimization. Conspicuously absent from this list, is Visual Studio. So, we are still left wondering if, in Visual Studio, should redundant #include guards be used, or #pragma once.

For small to medium sized projects, #pragma once is certainly convenient. For large sized projects where compile time become a factor during development, redundant #include guards give a developer greater control over the compilation process. Anyone who is managing or architecting large-scale projects should have Large Scale C++ Design in their library--it talks about and recommends redundant #include guards.

Possibly of greater benefit than redundant include guards is smart usage of #includes. With C++ templates and STL becoming more popular, method implementations are migrating from .cpp files to .h files. Any header dependencies the .cpp implementation would have had, is now necessarily having to migrate to the .h file. This increases compilation time. I have often seen developers stack lots of unnecessary #include's into their header files so they won't have to bother identifying the headers they actually need. This also increases compile time.

0

The #pragma once is a nicer form of an include guard. If you use it, you don't need the include guard based on #define.

In general, this is a better approach, since it prevents name clashes from being able to break an include guard.

That being said, the include guard should be in the header file, not wrapping the include. Wrapping the include should be completely unnecessary (and will likely confuse other people down the road).


Edit:

I think we are talking about two different things. My question is whether we should use include guard when we use a pre-existing head file that has either #pragma once or #ifndef xxx

In that case, no. If the header has a proper guard, there is no reason to try to avoid including it. This just adds confusion and complexity.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • @g-makulik What compilers are you using that don't support it? It's supported by pretty much all major, modern C++ compilers. – Reed Copsey Feb 27 '13 at 18:25
  • I do the same as @g-makulik. I work on embedded systems as well, I don't use compiler extensions. That said, it comes down to your use case. Sometimes you *know* that your code will only ever be compiled by a specific subset of compilers. – Ed S. Feb 27 '13 at 18:36
0

That's not how include guards are used. You don't wrap your #includes in an include guard. A header file should wrap its own contents in an include guard. Whenever you write a file that will likely be included in others, you should do:

#ifndef _SOME_GUARD_
#define _SOME_GUARD_

// Content here

#endif

With Visual Studio's implementation of the C++ library, that might be done by the string header having #pragma once or by checking #ifndef _STRING_.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • And, of course, you don't give your include guards names like `_SOME_GUARD`, because names that begin with an underscore followed by a capital letter and names that contain two sequential underscores are reserved to the implementation. – Pete Becker Feb 27 '13 at 19:56