473,385 Members | 1,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

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

Jun 20 '07 #1
18 2110
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
<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
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
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
"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
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
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
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
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
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
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
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
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
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
"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
<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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Steven T. Hatton | last post by:
Is there anything that gives a good description of how source code is converted into a translation unit, then object code, and then linked. I'm particularly interested in understanding why putting...
44
by: Neil Cerutti | last post by:
In Rob Pike's style guide he urges the following: Simple rule: include files should never include include files. If instead they state (in comments or implicitly) what files they need...
12
by: Francois Grieu | last post by:
Can #include safely use a preprocessing token, as in #define HEADERFILE "stdio.h" #include HEADERFILE int main(void) {return printf("Hello, world\n")*0;} TIA, François Grieu
14
by: Pedro Graca | last post by:
Imagine I have a structure with a size_t member: /* foo.h */ struct foo { char const *bar; size_t barlen; }; void make_foo(struct foo *p);
12
by: Thomas Carter | last post by:
Imagine that there is some include file f.h that contains the following line: typedef unsigned int ui32 ; My question is: If I have a C source file F.c that includes f.h, is it possible for...
3
by: linq936 | last post by:
Hi, I have a C++ header file like this, #include "MyClass1.h" class MyClass2{ private: MyClass1* c1; };
4
by: Christoph Scholtes | last post by:
Hi, I have some questions about header files: Say I have a file functions.c which contains a couple of functions. I have declared some structs in this file too. The structs are defined in...
14
by: JoeC | last post by:
I have been writing games and I also read about good programming techniques. I tend to create large objects that do lots of things. A good example I have is a unit object. The object controls...
5
by: Francois Grieu | last post by:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at #define a(b) b int main(void){return a( #if 0 #endif 0);} More generally, this compiler seems confused by any preprocessing...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.