#pragma once and #ifndef/#endif 
Author Message
 #pragma once and #ifndef/#endif

Just a quick couple of questions. It isn't a major problem, but I'd like to
get it right.

In the past I have generally used '#ifndef/#define/#endif' in my headers to
eliminate multiple includes, but every so often #pragma once catches my eye
again. I know it is a Microsoft extension, but I would assume the compiler
will make best use of it if I use both (since I intend my code to be safe
for non-MS compilers).

So my questions;-

What '#ifdef/endif' clause should I put round the '#pragma once' to ensure
that only the MS compilers (and the right versions of them) see it?

Since I am covering both methods, should the '#pragma once' be inside the
'#ifndef/#define/#endif', or outside it? (or doesn't it matter?)

TIA,

A Ratcliffe



Sat, 16 Apr 2005 20:09:51 GMT  
 #pragma once and #ifndef/#endif

Quote:

>> Since I am covering both methods, should the '#pragma once' be
>> inside the '#ifndef/#define/#endif', or outside it? (or doesn't it
>> matter?)

> I guess it doesn't really matter.

Dave,

Do you know what benefit the '#pragma once' provides if you're also using
traditional #ifndef include guards for backwards compatibility?

I'd assumed that its inclusion in ClassWizard (R.I.P.) generated files was
merely 'promotional'.

Will



Sat, 16 Apr 2005 23:37:57 GMT  
 #pragma once and #ifndef/#endif

Quote:
>What '#ifdef/endif' clause should I put round the '#pragma once' to ensure
>that only the MS compilers (and the right versions of them) see it?

#if _MSC_VER > 1000
#pragma once
#endif

Quote:
> Since I am covering both methods, should the '#pragma once' be inside the
>'#ifndef/#define/#endif', or outside it? (or doesn't it matter?)

I guess it doesn't really matter.

Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq



Sat, 16 Apr 2005 22:53:12 GMT  
 #pragma once and #ifndef/#endif


Quote:

> >> Since I am covering both methods, should the '#pragma once' be
> >> inside the '#ifndef/#define/#endif', or outside it? (or doesn't it
> >> matter?)

> > I guess it doesn't really matter.

> Dave,

> Do you know what benefit the '#pragma once' provides if you're also using
> traditional #ifndef include guards for backwards compatibility?

When the compiler encounters #pragma once in a file where it's encoutered it
before, it immediately abandons parsing the file & returns to the file that
#included it.   With the #ifndef/#endif pattern, the compiler continues to
tokenize the balance of the file until it finds the matching #endif, and
then parses whatever comes after it (which is, hopefully, nothing).

So, in theory, #pragma once is slightly more efficient.  Some compilers (but
not VC, I believe) recognize the #ifdef/#endif idiom and effectively
translate it into #pragma once internally.  Allegedly GCC is one such
compiler.

-cd



Sat, 16 Apr 2005 23:45:04 GMT  
 #pragma once and #ifndef/#endif



Quote:

> > When the compiler encounters #pragma once in a file where it's
> > encoutered it before, it immediately abandons parsing the file &
> > returns to the file that #included it.   With the #ifndef/#endif
> > pattern, the compiler continues to tokenize the balance of the file
> > until it finds the matching #endif, and then parses whatever comes
> > after it (which is, hopefully, nothing).

> > So, in theory, #pragma once is slightly more efficient.

> Thanks.

> I would think that preprocessing headers within '#if dont-use-this-bit'
> blocks is such a trivial proportion of the time spent on compiling C++
that
> there probably isn't much in it.   One would hope that the compiler would
be
> smart enough not to be bothering with token-substitution tasks as it went
> looking for the #endif.

The compilers that are smart enough to do this optimization, can set up a
table of already parsed files so that when they encounter another #include
for the same file, they can just skip it altogether ("been there, done
that").

Bo Persson



Sun, 17 Apr 2005 01:59:19 GMT  
 #pragma once and #ifndef/#endif



Quote:
> Thanks for all your help.

> From what you have said, it suggests that the #ifdef _MSC_VER../#pragma
> once/#endif should be placed before the #ifndef/#define/endif for
> efficiency. please let me know if that is right?

For MSC, yes. For other compilers, no!

Having two separate #ifdef blocks in the file, might fool some semi-smart
compiler into *not* recognizing the optimization opportunity!

If you have such gigantic include files that this actually makes a
difference, you should probably look into precompiled headers instead.  :-)

Bo Persson



Sun, 17 Apr 2005 02:04:47 GMT  
 #pragma once and #ifndef/#endif
Thanks for all your help.

From what you have said, it suggests that the #ifdef _MSC_VER../#pragma
once/#endif should be placed before the #ifndef/#define/endif for
efficiency. please let me know if that is right?

Yours,

A Ratcliffe



Quote:




> > >> Since I am covering both methods, should the '#pragma once' be
> > >> inside the '#ifndef/#define/#endif', or outside it? (or doesn't it
> > >> matter?)

> > > I guess it doesn't really matter.

> > Dave,

> > Do you know what benefit the '#pragma once' provides if you're also
using
> > traditional #ifndef include guards for backwards compatibility?

> When the compiler encounters #pragma once in a file where it's encoutered
it
> before, it immediately abandons parsing the file & returns to the file
that
> #included it.   With the #ifndef/#endif pattern, the compiler continues to
> tokenize the balance of the file until it finds the matching #endif, and
> then parses whatever comes after it (which is, hopefully, nothing).

> So, in theory, #pragma once is slightly more efficient.  Some compilers
(but
> not VC, I believe) recognize the #ifdef/#endif idiom and effectively
> translate it into #pragma once internally.  Allegedly GCC is one such
> compiler.

> -cd



Sun, 17 Apr 2005 00:24:41 GMT  
 #pragma once and #ifndef/#endif

Quote:

> When the compiler encounters #pragma once in a file where it's
> encoutered it before, it immediately abandons parsing the file &
> returns to the file that #included it.   With the #ifndef/#endif
> pattern, the compiler continues to tokenize the balance of the file
> until it finds the matching #endif, and then parses whatever comes
> after it (which is, hopefully, nothing).

> So, in theory, #pragma once is slightly more efficient.

Thanks.

I would think that preprocessing headers within '#if dont-use-this-bit'
blocks is such a trivial proportion of the time spent on compiling C++ that
there probably isn't much in it.   One would hope that the compiler would be
smart enough not to be bothering with token-substitution tasks as it went
looking for the #endif.

Every little helps, though...

Cheers,

Will



Sun, 17 Apr 2005 01:03:59 GMT  
 #pragma once and #ifndef/#endif

Quote:




> > > When the compiler encounters #pragma once in a file where it's
> > > encoutered it before, it immediately abandons parsing the file &
> > > returns to the file that #included it.   With the #ifndef/#endif
....

> The compilers that are smart enough to do this optimization, can set up a
> table of already parsed files so that when they encounter another #include
> for the same file, they can just skip it altogether ("been there, done
> that").

> Bo Persson


No they can't do that: skip already parsed file, because of
preprocessor directive that can change between include they must
reparse the whole file.

In general I think that the second inclusion of a file should bring
the same definitions as the first time,  but I've seen in the past
some "sicko" who did create include files that had to be included
twice. The first time just a subset of the file was used, then the
second time, with other #define, it would bring in more definitions.

Daniel Anderson



Sun, 17 Apr 2005 22:32:56 GMT  
 #pragma once and #ifndef/#endif

Quote:
> In general I think that the second inclusion of a file should bring
> the same definitions as the first time,  but I've seen in the past
> some "sicko" who did create include files that had to be included
> twice. The first time just a subset of the file was used, then the
> second time, with other #define, it would bring in more definitions.

This was a widely used technique for implementing "generic code" in
pre-template C++.  Unfortunately, there's some of that code still kicking
around.

-cd



Sun, 17 Apr 2005 23:07:05 GMT  
 #pragma once and #ifndef/#endif


Quote:


> > In general I think that the second inclusion of a file should bring
> > the same definitions as the first time,  but I've seen in the past
> > some "sicko" who did create include files that had to be included
> > twice. The first time just a subset of the file was used, then the
> > second time, with other #define, it would bring in more definitions.

> This was a widely used technique for implementing "generic code" in
> pre-template C++.  Unfortunately, there's some of that code still kicking
> around.

> -cd

With #pragma once the compiler only opens the file once: if it detects a
second #include of the file it will completely ignore the #include. So if
you are playing tricks with #ifdef and header files do not use #pragma once.

--
Jonathan Caves
Microsoft Corporation

This posting is provided "AS IS" with no warranties, and confers no rights.



Mon, 18 Apr 2005 06:50:07 GMT  
 #pragma once and #ifndef/#endif

Quote:
> Now a user is trying to be smart and adds

> #ifdef _MSC_VER
> #pragma once
> #endif

> before the original #ifndef directive.

> How many compilers will now recognize that *both* conditional blocks
> can be skipped, and avoid parsing the file?

Of course, the #ifdef/#pragma once/#endif can simply be placed inside the
original #ifdef include guard, which is how I've always seen this idiom
applied..

--
Jeff Peil



Mon, 18 Apr 2005 12:09:32 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. ifndef/define/endif

2. Some help with #define, #ifndef, #endif

3. #ifndef... #endif problem

4. #ifndef..#endif

5. VC++4.0 #pragma line executes even when #ifndef, #endif block is not true??

6. VC++4.0 #pragma line executes even when #ifndef, #endif block is not true??

7. #if !defined, #pragma once

8. #if !defined, #pragma once

9. #pragma once

10. Adding #pragma once made my build time longer

11. #pragma once vs. #if !defined(file_h_included)

12. _MSC_VER wrong when wrapping #pragma once?

 

 
Powered by phpBB® Forum Software