Sutters guidelines and redundant include guards

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
apm35 (156)
12/14/2004 7:54:23 PM
comp.lang.c++.moderated 10706 articles. 11 followers. allnor (8507) is leader. Post Follow

7 Replies
391 Views

Similar Articles

[PageSpeed] 43
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
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
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
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
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
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
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
Ben
12/17/2004 4:40:47 AM
Reply:
Similar Artilces:

Sutter's Mill
Hi All, I've been reading Sutter's column in C/C++ Users Journal - "Compatibilties", and find myself a little bit confused. To put a long story short, Sutter describes the Binary compatibility problems in the C++ world. As far as I understood, In case you or a third party library use user defined classes even like std::string, you should always compile and link your code with the same compiler options (for example the same -O). That sound a little bit scarry. Lets take for example some kind of a GUI library, that happen to be written in C++ and has user defined classes/str...

How do I set the DLL thread parameters for a DLL call that includes a dialog?
A friend of mine has written code in Java and created a DLL for me to use in LabVIEW. It works great but we have run into problems when we want to present a dialog from the DLL. The Java dialog shows up fine and returns the parameters as expected&nbsp;but the LabVIEW window in the background (the main window) is not updated while the dialog is up... As a result, if the Java dialog window is moved by the user&nbsp;it leaves white areas behind it. The interesting thing is that when the dialog is moved outside the LabVIEW area, the other applications it is moved over manage to update thei...

Herb fought the law--Amdahl's Law, that is--and Herb won-DDJ --- Did sutter really fight?
Hey, I just went throught sutter article titled Break Amdahl's law and subtitled Herb fought the law--Amdahl's Law, that is--and Herb won-DDJ. After reading this article I found no much information than an explanation to Amdahl's law and Gustafson's law. I wonder why Dr Dobbs Journal still tells Herb fought with some kind of law and won. If someone has ever tried to break the Amdahl's law it is Gustafson. And even Gustafson named his paper "Reevaluating Amdahl's Law". http://amalp.blogspot.com/2008/02/did-herb-sutter-fight-with-amdahls-law.html - Plea...

Always Include Associations
Hi All, This is probably really simple, but I couldn't find a solution anywhere. Is there a mechanism in Ruby/Rails whereby I can tell a class to always = pre-load the associations for it (rather than specifying :include ... for = every occurance)? -- ...

Posting Guidelines for comp.lang.perl.misc ($Revision: 1.9 $) #162
Outline Before posting to comp.lang.perl.misc Must - Check the Perl Frequently Asked Questions (FAQ) - Check the other standard Perl docs (*.pod) Really Really Should - Lurk for a while before posting - Search a Usenet archive If You Like - Check Other Resources Posting to comp.lang.perl.misc Is there a better place to ask your question? - Question should be about Perl, not about the application area How to participate (post) in the clpmisc community - Carefully choose the contents of your Subject header ...

redundant switches spanning-tree question
have a 3548 and a 3550 each cross-connected and trunking to two 7206s. Looking at spanning-tree info on the two switches, they both declare themselves root bridge for the same vlans. spanning-tree isn't enabled on the routers. up to this point there aren't any redundant vlans across the two switches, which is why i'm guessing there have been no issues. now, however, i'm tasked with setting up redundant connections from a pix failover pair, one to each switch. hsrp will be configured on router subinterfaces for their vlan. since at the moment the switches aren't pas...

How to weed out redundancy in row matrix?
Hi All, My field work had yielded data matrices amounting to thousands. I am now in the process of weeding out redundancy in my data set(which come in a packet of 15000 by 8 matrix). My task is simply to weed out the replicate any row matrix(compromising of 8 values) in the 15k rows. I've used sortrows to arrange them in descending order and manually identify the redundancy(which is rather time consuming n error prone). My question here is as to which function(s) can help computerize the weeding out process after sorting. Any clue? "abdulhallis aziz" <abdulhallis@unimap...

Sutter you fascinate me
It would be interesting to meet in real life. Musatov Martin Musatov wrote: > It would be interesting to meet in real life. Musatov usenet posting is a subset of the set "real life" which is to say, that, the set "usenet posting" is contained within the set "real life" agree or disagree? oh, and, let's say that a given person, you for example, cannot eat drink or sleep until they reply to this message, so, while it is quite possible that such a person may never make such a decision to reply, they may very well, "...

Functions: overloading, including functions not named the same as the file
How can I include a file which has several functions and then, if one of the function names is named the same as a function in another file, make sure the right one is called? (I hope I'm asking this question clearly.) Here's what I really want to do: matrix1.m --------- [t_steps,s1] = ode45(@ODE_linear_fixed, t_steps, s0); % [t_steps,s1] = ode45(@ODE_cubic_periodic, t_steps, s0); % [t_steps,s1] = ode45(@ODE_fpu_periodic, t_steps, s0); % calculate the energy at each timestep ODE_linear_fixed.m ------------------ ....linear, fixed boundaries system here... ODE_cubic_periodic.m ----...

Posting Guidelines for comp.lang.perl.misc ($Revision: 1.9 $) #146
Outline Before posting to comp.lang.perl.misc Must - Check the Perl Frequently Asked Questions (FAQ) - Check the other standard Perl docs (*.pod) Really Really Should - Lurk for a while before posting - Search a Usenet archive If You Like - Check Other Resources Posting to comp.lang.perl.misc Is there a better place to ask your question? - Question should be about Perl, not about the application area How to participate (post) in the clpmisc community - Carefully choose the contents of your Subject header ...

redundant L2/L3 design and multiple hsrp standby interfaces
Topology: two access switches, which presently are not trunked, and two access routers, each cross-connected, trunking dot1q vlans, to both switches. Pix fo pair, one pix connected to each switch. So at any one time, one pix is active through one switch. It seems, that the ultimate redundancy would be derived by having a routable subinterface on each of the two router-switch trunks - i.e. two interfaces for each vlan on each router one connected to each switch. If you have only one of the trunks carrying traffic on each router, e.g,accessrouter1-accessswitch2, accessrouter2-accessswit...

[rfc-dist] BCP 146, RFC 5406 on Guidelines for Specifying the Use of IPsec Version 2
A new Request for Comments is now available in online RFC libraries. BCP 146 RFC 5406 Title: Guidelines for Specifying the Use of IPsec Version 2 Author: S. Bellovin Status: Best Current Practice Date: February 2009 Mailbox: bellovin@acm.org Pages: 13 Characters: 30393 See Also: BCP0146 I-D Tag: draft-bellovin-useipsec-10.txt URL: http://www.rfc-editor.org/rfc/rfc5406.txt The Security Considerations sectio...

Herb Sutter article on C++0x
Here is an overview on the current status of C++0x, written by Herb Sutter, which includes a discussion of what must be done in order to get the 'x' in C++0x not to be a hex digit, as well as the biggest things accepted and a couple things that couldn't be completed in time for the standard: http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!159.entry -- Marcus Kwok Replace 'invalid' with 'net' to reply --- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-c++@ncar....

DEC-C: Missing includes (CDA)
On a node which has only seen DEC-C (VAX VMS 7.2, DEC-C 6.0), the CDA includes are missing. CDA$DEF.H, cda$msg.h cda$ptp.h cda$typ.h ddif$def.h dtif$def.h (as per the old CDA programming documentation) On my now adult all-mighty Microvax II, in the old VAXC includes directory, those include files are present. While development of the CDA architecture has long ended, the actual CDA converter kernel (convert/document and its callable interface) has always remained with the owner of VMS (only shareable images went to a 3rd party), so the includes should continue to be included with VMS. ...

Does bash have include
Hey all, Does bash have the concept of include as in C. Creating functions and invoking in our daily scripts/apps. How do i implement that ? let me know more about that. Regards Prince On 9 Apr 2007 at 8:28, Prince of Code wrote: > Hey all, > > Does bash have the concept of include as in C. Creating functions and > invoking in our daily scripts/apps. > > How do i implement that ? let me know more about that. You use . ? -- email: echo t.adllkhsl@iypzavs.hj.br | tr a-gh-pq-z t-za-ij-s On Apr 9, 4:28 am, "Prince of Code" <princeofc...@gmail.com> wrote...

Brand New Ink Cartridges are 99 cents on eBay includes shipping
Has anybody tried them? Stan Gee "Just in case you are in the market for new ink cartridges, they are the cheapest on eBay. An example is if you own the Canon i960 printer. Go to eBay and type in keyword, "18 ink cartridge for Canon i960". The total price will be less then $18.00 shipped, that's about 99 cents each. It doesn't matter what quantity, what brand(Canon, Epson, HP, Lexmark), they are still the cheapest on eBay. Shop around for the best price, there is so much competition on eBay that the only real winner is the consumer. Sincerely, ...

Module#include witha block
I'd really like to use include in block form, so I can do something like this: def somefunc include Wx do f = Frame.new t = Window.new end end and the Wx:: would be implied only within the block. Any idea how I could do this? Thanks, Bill On Mon, 26 Jul 2004 12:51:52 +0900, Bill Atkins <dejaspam@batkins.com> wrote: > I'd really like to use include in block form, so I can do something like this: > > def somefunc > include Wx do > f = Frame.new > t = Window.new > end > end > > and the Wx:: would be implied only within the...

a very small js library to include GRAPH COMMAND (lines,points, circle etc) and MATHsimbols
I developed a little javascript library for implement instruction like LINE (x0,y0,x1,y1) or drawImage(x,y) and, to make it short, the graph commands of JAVA. It is based on the <span> tag. Also, based on the 'symbol' font and some trick with tables, i developed a library to make maths on a web page (dinamically so to have exercises always news for my students) for example the instruction ww(frac(intrnd(1/10),intrnd(1/10)) prints a casual fraction on the page and ww(exists,x,inset,A) prints the two mathematical symbols and 'x' and 'A'. This libraries have the ve...

Combining adjacent values --> removing redundant zeros
I have a vector that contains various value: given = [ 0 -1 2 0 0 0 0 1 1 0 0 0 -5 0 0 6 ]; I want to combine all the zeros into a single instance. desired = [ 0 -1 2 0 1 1 0 -5 0 6 ]; Does anyone know an easy way to do this in Matlab? Thanks. The best I can think of: a=[ 0 -1 2 0 0 0 0 1 1 0 0 0 -5 0 0 6 ]; a( (a(1:end-1)==0) & (a(2:end)==0) )=[]; "Pat Finder" <pfinder.nospam@netacc.net> wrote in message <g8c60o$ffi$1@fred.mathworks.com>... > I have a vector that contains various value: > > given = [ 0 -1 2 0 0 0 0 1 1 0 0 0 -5 0 0 6 ]; > &g...

===, include?, =~
I started this post after wondering why Set doesn't alias :=== to :include? That led me to look at ===, include?, and =~ for a variety of classes... The following table shows the results of executing pattern.send(method, arg) Pattern Arg === include? =~ /foo/ "foo" yes fails yes 0..10 5 yes yes Object#=~ ["foo"] "foo" Array#== yes Object#=~ Set.new ["foo"] "foo" Set#== yes Object#=~ {"foo", nil} "foo"...

*.answers submission guidelines
Archive-name: news-answers/guidelines Version: $Id: guidelines,v 2.56 2003/06/14 20:00:11 ngb Exp $ Posting-Frequency: monthly Copyright: see Section 5 [The most recent copy of this document can be obtained via anonymous FTP as rtfm.mit.edu:/pub/faqs/news-answers/guidelines. If you do not have access to anonymous FTP, you can get a copy by sending email to mail-server@rtfm.mit.edu with the command "send faqs/news-answers/guidelines" in the message.] ---------------------------------------------------------------------- Subject: 0. What is this document? This docu...

\include in latex without page breaks
Can \include be used in latex to include a paragraph without a pagebreak after the included text? For example, we would like to write a large document with many small sections, write each section as a separate file, and simply include them all in the main file. However, \include{section_filename} results in a pagebreak after the included section. Am Wed, 11 Jul 2007 03:15:02 -0700 schrieb cormacdefrein@gmail.com: > Can \include be used in latex to include a paragraph without a > pagebreak after the included text? For example, we would like to write > a large document with many smal...

Posting Guidelines for comp.lang.perl.misc ($Revision: 1.7 $) #58
Outline Before posting to comp.lang.perl.misc Must - Check the Perl Frequently Asked Questions (FAQ) - Check the other standard Perl docs (*.pod) Really Really Should - Lurk for a while before posting - Search a Usenet archive If You Like - Check Other Resources Posting to comp.lang.perl.misc Is there a better place to ask your question? - Question should be about Perl, not about the application area How to participate (post) in the clpmisc community - Carefully choose the contents of your Subject header ...

Posting Guidelines for comp.lang.perl.misc ($Revision: 1.5 $) #26
Outline Before posting to comp.lang.perl.misc Must - Check the Perl Frequently Asked Questions (FAQ) - Check the other standard Perl docs (*.pod) Really Really Should - Lurk for a while before posting - Search a Usenet archive If You Like - Check Other Resources Posting to comp.lang.perl.misc Is there a better place to ask your question? - Question should be about Perl, not about the application area How to participate (post) in the clpmisc community - Carefully choose the contents of your Subject header ...

Wildcard include in /etc/named.conf
Hi! I'm asking you if I can add wildcard include to /etc/named.conf: include "/etc/named.zones.*"; Now I'm including all singolar named.zones.xxx zone files and it's very unpleasant . Thanks for your attention ...