q0987
q0987

Reputation: 35982

is "Redundant #include Guards" necessary on Visual Studio?

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.

Upvotes: 3

Views: 1163

Answers (5)

Travis Green
Travis Green

Reputation: 31

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.

Upvotes: 2

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

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).

Upvotes: 5

Ed Swangren
Ed Swangren

Reputation: 124722

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.

Upvotes: 2

Joseph Mansfield
Joseph Mansfield

Reputation: 110698

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_.

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564641

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.

Upvotes: 0

Related Questions