By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,950 Members | 989 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,950 IT Pros & Developers. It's quick & easy.

About preprocessing and include guards

P: n/a
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

Jun 20 '07 #1
Share this Question
Share on Google+
18 Replies


P: n/a
On Wed, 20 Jun 2007 11:02:29 -0000, gu*****@gmail.com wrote:
>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...)
Because of the way your implementor decided to implement the whole
thing. Never try to deduce language rules by experimenting.

--
\|||/ Gennaro Prota - For hire
(o o) https://sourceforge.net/projects/breeze/
--ooO-(_)-Ooo----- (to mail: name . surname / yaho ! com)
Jun 20 '07 #2

P: n/a
<gu*****@gmail.comwrote in message
news:11**********************@p77g2000hsh.googlegr oups.com...
: 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?

The latter case is the standard behavior ( = actually including
and parsing the whole file).

The former case is an allowed optimization, under the "as if" rule.
Some compilers detect files whose structure is:
...only comments or blank lines...
#ifndef SOME_KEYWORD
#define SOME_KEYWORD

#endif
...only comments or blank lines...
They keep trace of the path and keyword, and avoid reloading the
file at all if the keyword is already defined.

If the file contains C++ statements, or any non-comment / non-blanks
outside of the #ifndef...#endif block, this specific optimization
cannot be performed.
So you should not need to worry about it...

Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com

Jun 20 '07 #3

P: n/a
On Wed, 20 Jun 2007 14:26:28 +0200, Ivan Vecerina wrote:
><gu*****@gmail.comwrote in message
news:11**********************@p77g2000hsh.googleg roups.com...
: 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?

The latter case is the standard behavior ( = actually including
and parsing the whole file).
"Standard" in what sense.
>The former case is an allowed optimization, under the "as if" rule.
Some compilers detect files whose structure is:
...only comments or blank lines...
#ifndef SOME_KEYWORD
#define SOME_KEYWORD

#endif
...only comments or blank lines...
They keep trace of the path and keyword, and avoid reloading the
file at all if the keyword is already defined.

If the file contains C++ statements, or any non-comment / non-blanks
outside of the #ifndef...#endif block, this specific optimization
cannot be performed.
Nope. EDG, for instance, documents to do the optimization even with

#pragma once
#ifndef A_H
#define A_H
...
#endif

--
\|||/ Gennaro Prota - For hire
(o o) https://sourceforge.net/projects/breeze/
--ooO-(_)-Ooo----- (to mail: name . surname / yaho ! com)
Jun 20 '07 #4

P: n/a
On 2007-06-20 13:02, gu*****@gmail.com wrote:
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?
Probably because you have a preprocessor smart enough not to include the
same file (as in path) twice, thus saving the time it takes to open the
file and pre-process it. And why would you want the latter behaviour
when the first is preferable?

--
Erik Wikström
Jun 20 '07 #5

P: n/a
"Gennaro Prota" <ad*****@yahoo.comwrote in message
news:bd********************************@4ax.com...
: On Wed, 20 Jun 2007 14:26:28 +0200, Ivan Vecerina wrote:
:
: ><gu*****@gmail.comwrote in message
: >news:11**********************@p77g2000hsh.googleg roups.com...
: >: 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?
: >
: >The latter case is the standard behavior ( = actually including
: >and parsing the whole file).
:
: "Standard" in what sense.

As defined in the ANSII/ISO C++ standard.
For instance ISO/IEC 14482, See §2.1 = Phases of translation.

: >The former case is an allowed optimization, under the "as if" rule.
: >Some compilers detect files whose structure is:
: ...only comments or blank lines...
: #ifndef SOME_KEYWORD
: #define SOME_KEYWORD
: >
: #endif
: ...only comments or blank lines...
: >They keep trace of the path and keyword, and avoid reloading the
: >file at all if the keyword is already defined.
: >
: >If the file contains C++ statements, or any non-comment / non-blanks
: >outside of the #ifndef...#endif block, this specific optimization
: >cannot be performed.
:
: Nope. EDG, for instance, documents to do the optimization even with
:
: #pragma once
: #ifndef A_H
: #define A_H
: ...
: #endif

#pragma once itself is a non-standard extension, implemented notably
by Microsoft's C++ compilers. As all #pragma directives, it should
be "ignored" by an implementation that does not understand it.
#pragma once being used in MSVC to request this exact same optimization
(not re-parsing the file if it is #included twice), it just makes
sense for EDG to support this extension in this way.
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com

Jun 20 '07 #6

P: n/a
On Jun 20, 3:34 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-06-20 13:02, gutm...@gmail.com wrote:
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?

Probably because you have a preprocessor smart enough not to include the
same file (as in path) twice, thus saving the time it takes to open the
file and pre-process it. And why would you want the latter behaviour
when the first is preferable?

--
Erik Wikström
First of all - thank you all for taking the time to respond.

Erik, obviously that is the preferable behavior when you're trying to
compile... I need to get some data from the preprocessed files, and
I'm currently deprived of that data due to the above optimization...
>The former case is an allowed optimization, under the "as if" rule.
Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?

Thanks again to everyone!
- Tali

Jun 20 '07 #7

P: n/a
On Wed, 20 Jun 2007 13:01:51 -0000, gu*****@gmail.com wrote:
>Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?
Do you have include guards for the included file?
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Jun 20 '07 #8

P: n/a
On Jun 20, 4:16 pm, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Wed, 20 Jun 2007 13:01:51 -0000, gutm...@gmail.com wrote:
Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?

Do you have include guards for the included file?

--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Roland - Yes, and I need them there, too.
Also, I forgot to mention we're talking about a huge amount of code. I
can't change the code, I can either change the preprocessor (currently
using g++) or use some g++ flag if exists (which I failed to find).
Thanks for taking the time to answer! :)
- Tali

Jun 20 '07 #9

P: n/a
On 2007-06-20 15:37, gu*****@gmail.com wrote:
On Jun 20, 4:16 pm, rpbg...@yahoo.com (Roland Pibinger) wrote:
>On Wed, 20 Jun 2007 13:01:51 -0000, gutm...@gmail.com wrote:
>Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?

Do you have include guards for the included file?

--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch

Roland - Yes, and I need them there, too.
If the data you need is inside these include guards then it does not
matter whether the file is parsed or not, the data will not be included
anyway. If it is not within the include guards but the file is not
parsed then you should report the bug to the gcc developers.

--
Erik Wikström
Jun 20 '07 #10

P: n/a
On Jun 20, 5:05 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-06-20 15:37, gutm...@gmail.com wrote:
On Jun 20, 4:16 pm, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Wed, 20 Jun 2007 13:01:51 -0000, gutm...@gmail.com wrote:
Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?
Do you have include guards for the included file?
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Roland - Yes, and I need them there, too.

If the data you need is inside these include guards then it does not
matter whether the file is parsed or not, the data will not be included
anyway. If it is not within the include guards but the file is not
parsed then you should report the bug to the gcc developers.

--
Erik Wikström
Erik,
It's not in the file at all - I just want to see all the included
files listed. It's not a bug, it's most certainly the intended
behavior of the preprocessor (optimized, of course), but I'd like to
turn that optimization off somehow.
Thanks again,
-Tali

Jun 20 '07 #11

P: n/a
gu*****@gmail.com a écrit :
On Jun 20, 5:05 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-06-20 15:37, gutm...@gmail.com wrote:
>>On Jun 20, 4:16 pm, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Wed, 20 Jun 2007 13:01:51 -0000, gutm...@gmail.com wrote:
Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?
Do you have include guards for the included file?
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Roland - Yes, and I need them there, too.
If the data you need is inside these include guards then it does not
matter whether the file is parsed or not, the data will not be included
anyway. If it is not within the include guards but the file is not
parsed then you should report the bug to the gcc developers.

--
Erik Wikström

Erik,
It's not in the file at all - I just want to see all the included
files listed. It's not a bug, it's most certainly the intended
behavior of the preprocessor (optimized, of course), but I'd like to
turn that optimization off somehow.
Thanks again,
If you use gcc, you can look at the -M flag which output all
dependencies from a source file (or -MM if you don't want system headers).

Note: this is OT here.

Michael
Jun 20 '07 #12

P: n/a
On Jun 20, 5:24 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
gutm...@gmail.com a écrit :
On Jun 20, 5:05 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-06-20 15:37, gutm...@gmail.com wrote:
>On Jun 20, 4:16 pm, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Wed, 20 Jun 2007 13:01:51 -0000, gutm...@gmail.com wrote:
Ivan, if this is an "allowed optimization" - can I cancel it? Is there
a preprocessor that doesn't do that?
Do you have include guards for the included file?
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Roland - Yes, and I need them there, too.
If the data you need is inside these include guards then it does not
matter whether the file is parsed or not, the data will not be included
anyway. If it is not within the include guards but the file is not
parsed then you should report the bug to the gcc developers.
--
Erik Wikström
Erik,
It's not in the file at all - I just want to see all the included
files listed. It's not a bug, it's most certainly the intended
behavior of the preprocessor (optimized, of course), but I'd like to
turn that optimization off somehow.
Thanks again,

If you use gcc, you can look at the -M flag which output all
dependencies from a source file (or -MM if you don't want system headers).

Note: this is OT here.

Michael
Sweet! That's good to know!
I'm actually trying to build an inclusion tree, so it looks like it
won't help me too much, As I don't have the depth data...
It also skips the second time you include a file so... :/
But thanks a lot Michael! :)

Jun 20 '07 #13

P: n/a
On Wed, 20 Jun 2007 14:44:55 +0200, Ivan Vecerina wrote:
>: >The latter case is the standard behavior ( = actually including
: >and parsing the whole file).
:
: "Standard" in what sense.

As defined in the ANSII/ISO C++ standard.
For instance ISO/IEC 14482, See §2.1 = Phases of translation.
I'd have thought that clause 16 played a role as well. Anyway, I think
you missed my point: there's always the as-if rule, which you
mentioned, and thus no requirement that the file contents actually
undergo all phases of translation again, as long as no difference is
detectable from observable behavior. This means that neither cases
violates the standard (as long as the optimization is done correctly).
>: >The former case is an allowed optimization, under the "as if" rule.
Exactly.
>: >Some compilers detect files whose structure is:
: ...only comments or blank lines...
: #ifndef SOME_KEYWORD
: #define SOME_KEYWORD
: >
: #endif
: ...only comments or blank lines...
: >They keep trace of the path and keyword, and avoid reloading the
: >file at all if the keyword is already defined.
: >
: >If the file contains C++ statements, or any non-comment / non-blanks
: >outside of the #ifndef...#endif block, this specific optimization
: >cannot be performed.
:
: Nope. EDG, for instance, documents to do the optimization even with
:
: #pragma once
: #ifndef A_H
: #define A_H
: ...
: #endif

#pragma once itself is a non-standard extension, implemented notably
by Microsoft's C++ compilers.
Again, you missed my point. I said "for instance". There can be other
non-comment/non-blanks which do not preclude the specific
optimization. You simply cannot state that, in general, "If the file
contains C++ statements, or any non-comment / non-blanks outside of
the #ifndef...#endif block, this specific optimization cannot be
performed". That's not true.

--
\|||/ Gennaro Prota - For hire
(o o) https://sourceforge.net/projects/breeze/
--ooO-(_)-Ooo----- (to mail: name . surname / yaho ! com)
Jun 20 '07 #14

P: n/a
On Jun 20, 4:51 pm, gutm...@gmail.com wrote:
On Jun 20, 5:24 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
I'm actually trying to build an inclusion tree, so it looks like it
won't help me too much, As I don't have the depth data...
It also skips the second time you include a file so... :/
If the goal is to build an inclusion tree, the obvious solution
is to not use the compiler at all; parsing just the #include
statements isn't so awfully difficult.

If you really want the compiler to do part of the job, the
"obvious" solution is to construct a wrapper which does nothing
but include the file in question, and preprocess that. It won't
give you the full tree, but it will give you the information
about which files are included from file X, which you can use to
build the full tree.

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
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

Jun 20 '07 #15

P: n/a
"Gennaro Prota" <ad*****@yahoo.comwrote in message
news:2t********************************@4ax.com...
: On Wed, 20 Jun 2007 14:44:55 +0200, Ivan Vecerina wrote:
....
: >: >The former case is an allowed optimization, under the "as if"
rule.
:
: Exactly.
:
: >: >Some compilers detect files whose structure is:
: >: ...only comments or blank lines...
: >: #ifndef SOME_KEYWORD
: >: #define SOME_KEYWORD
: >: >
: >: #endif
: >: ...only comments or blank lines...
: >: >They keep trace of the path and keyword, and avoid reloading the
: >: >file at all if the keyword is already defined.
....
: Again, you missed my point. I said "for instance". There can be other
: non-comment/non-blanks which do not preclude the specific
: optimization. You simply cannot state that, in general, "If the file
: contains C++ statements, or any non-comment / non-blanks outside of
: the #ifndef...#endif block, this specific optimization cannot be
: performed". That's not true.

I mentioned the "as if" rule, then illustrated why the OP was
observing the behavior that he reported, and explained why he
did not need to worry about it in practice.

Was your point relevant in the scope of trying to assist the OP ?

plonk
--Ivan

Jun 20 '07 #16

P: n/a
<gu*****@gmail.comwrote in message
news:11**********************@w5g2000hsg.googlegro ups.com...
I'm actually trying to build an inclusion tree, so it looks like
it won't help me too much, As I don't have the depth data...
It also skips the second time you include a file so... :/
But thanks a lot Michael! :)
If you haven't yet, give doxygen a try:
http://www.doxygen.org

It can build inclusion/dependency trees, and a number
of other things...
I hope this helps,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Jun 20 '07 #17

P: n/a
On Jun 20, 8:12 pm, "Ivan Vecerina"
<_INVALID_use_webfo...@ivan.vecerina.comwrote:
<gutm...@gmail.comwrote in message

news:11**********************@w5g2000hsg.googlegro ups.com...
I'm actually trying to build an inclusion tree, so it looks like
it won't help me too much, As I don't have the depth data...
It also skips the second time you include a file so... :/
But thanks a lot Michael! :)

If you haven't yet, give doxygen a try:
http://www.doxygen.org

It can build inclusion/dependency trees, and a number
of other things...

I hope this helps,
Ivan
--http://ivan.vecerina.com/contact/?subject=NG_POST<- email contact form
Thanks Ivan, but sadly doxygen can't help me here. The problems of
adapting to an existing situation :)
Still would be happy if anyone knows how to "turn off" the
preprocessor optimization :)
Thanks to everyone!
- Tali

Jun 21 '07 #18

P: n/a
James Kanze a écrit :
On Jun 20, 4:51 pm, gutm...@gmail.com wrote:
>On Jun 20, 5:24 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
>I'm actually trying to build an inclusion tree, so it looks like it
won't help me too much, As I don't have the depth data...
It also skips the second time you include a file so... :/

If the goal is to build an inclusion tree, the obvious solution
is to not use the compiler at all; parsing just the #include
statements isn't so awfully difficult.
A library like freetype2 uses defined for files to include. I guess at
least in this case the preprocessor would be needed.
>
If you really want the compiler to do part of the job, the
"obvious" solution is to construct a wrapper which does nothing
but include the file in question, and preprocess that. It won't
give you the full tree, but it will give you the information
about which files are included from file X, which you can use to
build the full tree.
IMHO it is the best solution. But there is still the problem of the
include path passed to the actual compiler.

Michael
Jun 21 '07 #19

This discussion thread is closed

Replies have been disabled for this discussion.