C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Sutters guidelines and redundant include guards

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
apm35@student.open.ac.uk
Guest





PostPosted: Tue Dec 14, 2004 7:54 pm    Post subject: Sutters guidelines and redundant include guards Reply with quote



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! ]
Back to top
Dave O'Hearn
Guest





PostPosted: Wed Dec 15, 2004 4:44 am    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote



[email]apm35 (AT) student (DOT) open.ac.uk[/email] wrote:
Quote:
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?

Quote:
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! ]

Back to top
Ben Hutchings
Guest





PostPosted: Wed Dec 15, 2004 4:45 am    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote



[email]apm35 (AT) student (DOT) open.ac.uk[/email] wrote:
Quote:
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.

Quote:
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! ]

Back to top
Allan W
Guest





PostPosted: Wed Dec 15, 2004 6:16 pm    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote

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! ]
Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Dec 15, 2004 6:17 pm    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote

Ben Hutchings wrote:

Quote:
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! ]

Back to top
Dave O'Hearn
Guest





PostPosted: Thu Dec 16, 2004 1:20 pm    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote

Allan W wrote:
Quote:
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! ]

Back to top
apm35@student.open.ac.uk
Guest





PostPosted: Thu Dec 16, 2004 1:32 pm    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote

Dave O'Hearn wrote:
Quote:
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).

Quote:

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.

Quote:
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! ]

Back to top
Ben Hutchings
Guest





PostPosted: Fri Dec 17, 2004 4:40 am    Post subject: Re: Sutters guidelines and redundant include guards Reply with quote

[email]apm35 (AT) student (DOT) open.ac.uk[/email] wrote:
Quote:
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! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.