Sutters guidelines and redundant include guards

  • Permalink
  • submit to reddit
  • Email
  • Follow


I have just come across the guideline: "Always write internal #include
guards. Never write external #include guards." and I have a few
comments about it:

1. Sutter's example is not quite correct. The code fragment he gives is
for headers that do not have a predictable guard (e.g system headers or
third-party headers). When the guard is predictable the construct is
(slightly) smaller, e.g:

#ifndef INCLUDED_FOOBAR_H
#include "foobar.h"
#endif

2. Microsoft compilers and other compilers aimed at Windoze machines do
indeed make redundant include guards, er, redundant. However, Unix
compilers have a long way to go before they catch up in this area.
There maybe perhaps could still be some benefit from using them for
code that has to compile on Unix.

3. IMO the predictable aspect of the include guard has been glossed
over, leaving the impression that the redundant guard construct is
high-maintainance. Well it would be if the guard was not predictable.
But it is predictable, using whatever rules are established in the
corporate coding stds. This reduces the maintainance costs and leaves
one with what is probably the main objection: the code is longer and
more ugly. This is still an understandable reason for avoiding them but
is less strong than Sutter's guideline suggests.

4. Given the above, whether to use them or not boils down to whether or
not the improved builds times is a gain that is worth the cost of the
code uglification. This would have to be measured. Given the
predictable mechanical nature of the redundant guards surely there must
be a tool by now that would convert to use redundant guards, then we
could measure the improvement. So the guideline seems to come down a
little heavy on a measure that could have some benefit.
Regards,

Andrew Marlow


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply apm35 (156) 12/14/2004 7:54:23 PM

See related articles to this posting


apm35@student.open.ac.uk wrote:
> 1. Sutter's example is not quite correct. The code fragment he
> gives is for headers that do not have a predictable guard (e.g
> system headers or third-party headers). When the guard is
> predictable the construct is (slightly) smaller, e.g:
>
> #ifndef INCLUDED_FOOBAR_H
> #include "foobar.h"
> #endif

Why would you need to write the external guard, though? Maybe you
weren't aware of the optimizations done by UNIX compilers?

> 2. Microsoft compilers and other compilers aimed at Windoze
> machines do indeed make redundant include guards, er, redundant.
> However, Unix compilers have a long way to go before they catch
> up in this area. There maybe perhaps could still be some benefit
> from using them for code that has to compile on Unix.

Unfortunately, #pragma once is not standard, and it's not just an
optimization. Often, including multiple times generates wrong code,
like violating the ODR. You still need the redundant include guards for
portable code.

Most UNIX compilers have their own optimization, instead of #pragma
once, and it is better. They recognize the structure of a redundant
include guard, and will not read the file multiple times, as they
understand it's a no-op. This fails gracefully on compilers that don't
support the optimization.

However, Windows compilers tend not to support the optimization, so
there is a lot of code like this,

#ifndef SOMEFILE_H
#define SOMEFILE_H
#ifndef LACKS_PRAGMA_ONCE
#pragma once
#endif // !LACKS_PRAGMA_ONCE
// ...
#endif // !SOMEFILE_H

I believe ACE starts every hearder with a construct like that. It does
work though, and it should eliminate any motive for external include
guards unless you're using a terribly dated compiler.

-- 
Dave O'Hearn


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Dave 12/15/2004 4:44:07 AM

apm35@student.open.ac.uk wrote:
> I have just come across the guideline: "Always write internal #include
> guards. Never write external #include guards." and I have a few
> comments about it:
> 
> 1. Sutter's example is not quite correct. The code fragment he gives is
> for headers that do not have a predictable guard (e.g system headers or
> third-party headers). When the guard is predictable the construct is
> (slightly) smaller, e.g:
> 
> #ifndef INCLUDED_FOOBAR_H
> #include "foobar.h"
> #endif
> 
> 2. Microsoft compilers and other compilers aimed at Windoze machines do
> indeed make redundant include guards, er, redundant.

Assuming you don't include the a header file through two different
paths that it doesn't realise are the same - though that would be
rather silly.

> However, Unix compilers have a long way to go before they catch up
> in this area.
<snip>

GCC's preprocessor recognises the ifndef...#define...#endif pattern
#and can skip the whole file if it's included again.  Any other
implementer is free to do the same.  There's no need for a
non-standard extension, or the external guards.  This also avoids the
problem of having to know for certain whether two paths point to the
same file.

-- 
Ben Hutchings
compatible: Gracefully accepts erroneous data from any source

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Ben 12/15/2004 4:45:34 AM

I know that not every platform supports #pragma once. But does anybody
know of a platform where it does something undesirable?

IMO, warnings would count as undesirable if there was no easy way to
supress them. But according to the standard (16.6):
Any pragma that is not recognized by the implementation is ignored.


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Allan 12/15/2004 6:16:26 PM

Ben Hutchings wrote:

> GCC's preprocessor recognises the ifndef...#define...#endif pattern
> #and can skip the whole file if it's included again.  Any other
> implementer is free to do the same.  There's no need for a
> non-standard extension, or the external guards.  This also avoids the
> problem of having to know for certain whether two paths point to the
> same file.

It's worth noting that GCC has done this for quite some time now, at
least ten years.  It's surprising that so few other compilers have
adopted the technique.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply kanze 12/15/2004 6:17:10 PM

Allan W wrote:
> I know that not every platform supports #pragma once. But does
> anybody know of a platform where it does something undesirable?
>
> IMO, warnings would count as undesirable if there was no easy
> way to supress them. But according to the standard (16.6):
> Any pragma that is not recognized by the implementation is
> ignored.

I put it in the !LACKS_PRAGMA_ONCE test because older versions of gcc
issue a warning that "`#pragma once' is obsolete". It's annoying, and I
don't know how to disable it. gcc 3.4 has correct support for pragma
once and doesn't issue the warning.

Both gcc and MSVC++ issue warnings on unrecognized pragmas, but they
both have ways to disable them. In general though, I just find pragmas
scary, and I like to #ifdef them.

-- 
Dave O'Hearn


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Dave 12/16/2004 1:20:47 PM

Dave O'Hearn wrote:
> including multiple times generates wrong code,
> like violating the ODR. You still need the redundant include guards
for
> portable code.

I think you are confusing redundant include guards with conventional
include guards. Conventional include guards are used to protect againts
harmful results if a file is included multiple times in a TU. This is
done by the file beginning with #ifndef guardname #define guardname
blah-blah #endif. This protects against ODR etc. Redundant include
guards are an ADDITIONAL measure where the include guard macro is
tested to ensure that the #include is not performed if the inclusion
has already been made.

With conventional include guards the header may be parsed many times
but each time other than the first is effectively a no-op. However, the
use of conventional include guards without the additional measure of
redundant include guards means that extra work is done in finding and
opening the file and parsing its contents (albeit the contents will be
quickly scanned until the closing #endif is encountered).

>
> Most UNIX compilers have their own optimization, instead of #pragma
> once, and it is better. They recognize the structure of a redundant
> include guard,

They recognise the construct of a *conventional* include guard. And so
the cost of finding and opening the file (which is large compared to
the cost of skipping to the closing #endif) is still incurred.

> work though, and it should eliminate any motive for external include
> guards unless you're using a terribly dated compiler.

One of my points was that commercial unix compilers are not exactly
leading edge and so do not (AFAIK) have any work done in this area.
-Andrew M.


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply apm35 12/16/2004 1:32:15 PM

apm35@student.open.ac.uk wrote:
> Dave O'Hearn wrote:
>> including multiple times generates wrong code,
>> like violating the ODR. You still need the redundant include guards
>> for portable code.
<snip> 
> With conventional include guards the header may be parsed many times
> but each time other than the first is effectively a no-op. However, the
> use of conventional include guards without the additional measure of
> redundant include guards means that extra work is done in finding and
> opening the file and parsing its contents (albeit the contents will be
> quickly scanned until the closing #endif is encountered).
<snip>

A smart preprocessor can identify the guard macro the first time a
file is included and check it the second time before opening the file.
(It is reasonable to assume that source files are not modified during
compilation.)  This is what GCC's preprocessor does. See
<http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libcpp/files.c?rev=1.1.2.3>
and in particular the function should_stack_file.

-- 
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Ben 12/17/2004 4:40:47 AM
comp.lang.c++.moderated 10647 articles. 9 followers. Post

7 Replies
274 Views

Similar Articles

[PageSpeed] 50


  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

Comments outside include guards (from a Sutter/Alexandrescu advice)
Hi, after several "tweaks" I think I've finally found a file layout which I like for my code (in terms of where the copyright line and the license reference go, where the vim modeline etc.). For included files, I've stuck so far to the suggestion in C++ Coding Standards which says: Don't try to be clever: Don't put any code or comments before and after the guarded portion, and stick to the standard form as shown. Today's preprocessors can detect include guards, but they might have limited intelligence and expect the guard code to appear exact...

Consider using redundant include guards to improve ACE compile time
I just thought I would offer a suggestion that I believe would significantly improve compile times for ACE/TAO/CIAO. Putting redundant include guards in the header files reduces compile time by eliminating the need for the preprocessor to read header files that have already been included elsewhere. For example, Thread_Manager.h includes Thread.h as do a number of other files. Each time the preprocessor encounters an include for Thread.h it has to go out to disk and open the file only to discover the include guard inside Thread.h. It then reads to the end of the #ifndef section and su...

[ace-users] Re: Consider using redundant include guards to improve ACE compile time
Hi Greg, >> I just thought I would offer a suggestion that I believe would significantly >> improve compile times for ACE/TAO/CIAO. Putting redundant include guards in >> the header files reduces compile time by eliminating the need for the >> preprocessor to read header files that have already been included elsewhere. This topic has been discussed extensively in the past on various mailing lists. Basically, the approach that Lakos suggests is VERY messy and hard to maintain, which is why we won't implement it. Moreover, good C++ preprocessors already s...

[9fans] Include guards and multiple includes
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I'm trying to convince some non-believers that include files should not include other include files, and that instead they should state their dependencies; they want hard data before they commit to such a scheme. Is there some study kicking around that I could point them at rather than re-factor our code base and time the resulting builds? I know the plan9 headers largely follow this pattern. Paul -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (Darwin) iD8DBQFFORlRpJeHo/Fbu1wRAlExAKCsTZtCcW9FlqvUwllBye9EgRGqGwCgnYZn 0QcMNw3...

About preprocessing and include guards
Say you have a file, a.h with an include guard. If you include it twice and look at the preprocessed output, you see there's no sign for the second inclusion. However, if you include it twice - once from a relative path, and once from an absolute one - you see that the second inclusion indeed occurs (enters the file and leaves immediately due to the include guard). Why does this happen (I have my speculations, but I want some reassurance...), and is there any way to make it always act like in the latter case? Thanks, - Tali On Wed, 20 Jun 2007 11:02:29 -0000, gutmant@gmail.com wrote: ...

Redundant behavior in coding guideline
Some of the coding guideline are mandatory, and even the format or layout of the text of the source code also should be followed. There's plenty of codes like the following snippet. Do you think the "re-evaluating the previous condition" is necessary and should be avoided though it's one of your coding guideline? And yes, there's plenty of code like this in many projects. 78 /* Error handling */ 79 if ((NULL == p_SrcNm) || (NULL == p_DestNm)) 80 { 81 lb_RetVal = false; 82 83 /* some other things special here ... */ ...

Include guards and inclusion order
Hello group, there are these moments when I just hate C++. This is one of them. So, I've been working on this project for a long time, classes have grown and become quite many, now it's time for the "inclusion fiasco". I've used include guards to protect my header files and always included the necessary includes so my include files are parsed correctly. I.e. I have constructs like Vehicle.hpp: #ifndef VEHICLE_HPP #define VEHICLE_HPP #include <SDL.h> #include "Sound.hpp" #include "Map.hpp" #include "SpriteManager.hpp" class Vehic...

Redundant behavior in coding guideline #2
Some of the coding guideline are mandatory, and even the format or layout of the text of the source code also should be followed. There's plenty of codes like the following snippet. Do you think the "re-evaluating the previous condition" is necessary and should be avoided though it's one of your coding guideline? And yes, there's plenty of code like this in many projects. 78 /* Error handling */ 79 if ((NULL == p_SrcNm) || (NULL == p_DestNm)) 80 { 81 lb_RetVal = false; 82 83 /* some other things special here ... */ ...

Automatic trimming of redundant includes and protoypes?
Can anyone tell me of a program that does this? When working on large applications that promiscously include large header files, it would be nice to have an automatic way of figuing out which aren't needed any longer. Any IDEs? Or could someone give me a lint? Harald Korneliussen wrote: >... When working on large >applications that promiscously include large header files, it would be >nice to have an automatic way of figuing out which aren't needed any >longer. Gimpel's PC-Lint (commercial) will warn about unused and multiple included header files. Roberto Waltman ...

Multiple include guards in header files
The stand libary that is a part of my compiler (BC++) has the typical include guards in the header files, but it also wraps the #include of the header in files that use it: // _defs.h // #if !defined(___DEFS_H) #define ___DEFS_H // header stuff here #endif /* ___DEFS_H */ // stdarg.h // #if !defined(___DEFS_H) #include <_defs.h> #endif Is the guard in stdarg.h just to speed up compiles? It sure looks ugly and is a lot of typing to adopt such technique. Ted [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: ...

Need advice for redundancy connections guidelines.
I would like to have some servers and services available through different public IPs. I know how to distribute outgoing traffic from my server/services, but I'm in a bit of a mess with incomming one. Mainly I have doubts about DNS setup, since I have not time to study DNS in deepth. My main doubt is next: - Is it possible to manage public DNS servers (that's, DNS servers on "register.com" that I can manage just through a Web frontend) to distribute clients request through different IPs and setup some type of "fallback" if a public server/service IP is not avai...

header file without include guard
Hi, all: What will happen if header files with the exact same names but with different contents and declared/defined without include guard reside in the include path for the compiler? Are these header files are included more than once? If so, is it the lastest included file always overwrite the previous one? Is this behavior predictable? thanks. wenmang@yahoo.com wrote: > What will happen if header files with the exact same names but with > different contents and declared/defined without include guard reside in > the include path for the compiler? Nothing. They just reside there. ...

[vim] auto generate include guards
The subject says it all. Is there a way to get vim [script/tip] to automatically generate include guards in a empty c/c++ header file? For instance, if I use vim to create a new c/c++ header file, say foo.h, I'd like vim to "automatically" create the following include guards for me: #ifndef FOO_H #define FOO_H #endif /* FOO_H */ TIA, -- A ankurshah@cheerful.com (Ankur) wrote in news:83b4c08c.0405031410.ae940a3 @posting.google.com: > The subject says it all. Is there a way to get vim [script/tip] to > automatically generate include guards in a empty c/c...

finding redundant #includes to shorten compile time
Are there any C tools that can find redundant #includes in a project, so as to shorten compile time? Of course, eliminating single #includes by hand and determining if the recompile fails is one option, though that is an extremely manual and time-intensive approach. Thanks, -- Benjamin Benjamin Rutt <brutt+news@bloomington.in.us> wrote in news:wc3ptctv5d0.fsf@mu.cis.ohio-state.edu: > Are there any C tools that can find redundant #includes in a project, > so as to shorten compile time? Of course, eliminating single > #includes by hand and determining if the recompile fails...

Three #include guards, which will never break?
Sometimes programmers will define macros at command line like: $ gcc -DF1_H ... $ gcc -DF1_H=0 ... $ gcc -DF1_H=1 ... One of following three lines labeled as #1, #2, #3 may provide #include guard and avoid errors may be introduced by redundant #include. Is there any flaw with each of them? Which one will never break? #if F1_H /*#1*/ /*#if !defined(F1_H)*/ /*#2*/ /*#ifndef F1_H */ /*#3*/ #define F1_H /*more stuff here ...*/ #endif -- lovecreatesbeauty On 2006-06-07, lovecreatesbeauty <lovecreatesbeauty@gmail.com> wrote: > Sometimes programmers wil...

#browseDefinitionsOf: includes redundant item
Hello all, My current image is older than dirt, and so it's long past time to rebuild. Today, I noticed that browsing definitions of a particular method opens a method browser on a lot of correct stuff and to something that looked like a compilation failure, though it's not one. It instead looks like a compiled method that has not be gc'd. Double-clicking the offending entry in the method browser opens a CHB on the correct method with the correct source. The method browser also includes a separate line for the "same method" with the correct source; it...

Is it advisable to put include guard in .h and .cpp
Hi C++ Gurus, Is it advisable to put include guard in both .h and .cpp files. I am trying to do achieve these below: A.h ----- #ifndef A_h #define A_h class A { public: void test(); } #endif A.cpp ---- #include "A.h" #ifndef A_cpp #define A_cpp void A::test() { cout<<"Just a test"; } #endif B.cpp ------- #include "A.cpp" C.cpp #include "A.cpp" Thanks in advance.. HariS -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time p...

Re: [tao-users] IDL compiler
Hi, Unfortunately, there's no way to do that currently in the IDL compiler. The include_guard option you mention is used to force the application to include the 'safe_include' alternative instead of the usual *C.h - part of a scheme to facilitate the dynamic loading of some TAO libraries. Maybe the include_guard option can be adapted to your requirements. You can check out how it is used in TAO_IDL/be/be_codegen.cpp around line 169. The generation of the canonical include guard is just above it. This location in the file is in a method called start_client_header(). T...

Can you trick docstrip into never including into the output code which is not marked by any guard?
Hello! When writing commented source-files using docstrip, you can use so-called "guards" for marking code as optional. Optional code which is marked by some guard will only be included into the output if a corresponding option is present in the optionlist-argument of \generate's \from-macro. Code which is not marked by any guard will be included into the output in any case. Can you trick docstrip into never including into the output code which is not marked by any guard? [I didn't find anything in the docstrip-manuals/commented sources and anything I can think of means ...

Re: [tao-users] IDL compiler
Hi,=20 > -----Original Message----- > From: tao-users-bounces@cse.wustl.edu=20 > [mailto:tao-users-bounces@cse.wustl.edu] On Behalf Of Brian Lindahl > Sent: Tuesday, November 14, 2006 6:13 PM > To: tao-users@cse.wustl.edu > Subject: Re: [tao-users] IDL compiler - include guard modification >=20 > Took a look at it, looks like a pretty simple mod. So I'd add=20 > the option as a backend option (-Wb) as opposed to a regular=20 > option? Why? Rather, how do you decide between an option=20 > becoming a backend option, or a regular option? The ID...

Intelligent include-guard processing (C++ Coding Standards, Items 23 & 24)
Item 24 says we shouldn't place any comments before an include guard. This could apparently prevent compilers from using intelligence as mentioned in Item 23: "Many modern C++ compilers recognize header guards automatically ... and don't even open the same header twice". I suppose I should do some tests for myself to see how significantly the effect can be demonstrated on the compilers in use at work, but before I go to that effort can anyone tell me which compilers this applies to, or doesn't apply to? (My current code base almost universally has copyright etc co...

Includes and sub-includes
Hello all, We are currently changing our web server and, in the process, updating PHP version from 4.3.0 to 4.3.5. The problem we've got is that our way to include some files in other ones is no more working properly. The message we are getting looks like: "PHP Warning: main(..\db.inc.php): failed to open stream: No such file or directory in ..." Say we have this file structure: myApplication (dir) index.php include (dir) db.inc.php authentification (dir) user.inc.php ...

include files not being included
Hello, I'm running php 5.2.5 installed from ports on a FreeBSD machine with apache2 as the webserver. I've got php set up properly, but it doesn't include include files. If i do a phpinfo() in a file that works telling me php file processing is working fine. Yet if i have something like for an example: <html> <head> <title>Test of includes</title> </head> <body> <h1><? include "test-include.php"; ?></h1> <p>The above should have been included.</p> </body> </html> and in test-include.ph...

include failing to include...
Folks, I have a virtual server with an ISP and I had a web based application available for a customer to try out - it worked fine up until three weeks ago - nothing has changed since then (I am the only one with root password unless the ISP took control without my permission but I'd doubt this). I have Virtual (Named) Hosting enabled and I can test it via individual url's responding appropriately. On one specific URL I have an include as the first line... and there are no error messages in the error log file, the html is rendered just fine but various variables defined during the inc...