Skip to main content
GameDev.net gamedev.net
🔒 Locked

#pragma once vs. include guards

Started by Noods Sep 28, 2008 at 2:43 PM 25 replies 15.3k views
Original Post
Noods
Noods
I have read up on the pros and cons of #pragma once and include guards but I wanted to get a few opinions. Do you find yourself using #pragma once or include guards?
deadstar
deadstar
I use include guards, simply because Code::Blocks puts them there for me :)

I'm unsure there will be any difference between the two, I think most compilers have now caught up and handle it accordingly. Maybe some console developers here have some opinions?

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2   A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk
Mantear
Mantear
I always use header guards as they are guaranteed to always work.
Evil Steve
Evil Steve
Include guards. I really doubt that the time saved by using #pragma once will be noticible. If in doubt, you can always use both to get the best of both worlds.
Promit
Promit
Include guards will never hurt.
Pragma once will never hurt.

So I use both together.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
SiCrane
SiCrane
Quote:
Original post by Promit
Pragma once will never hurt.

Unless your code is compiled by an older version of gcc or LCC, both of which have had buggy implementation of pragma once such symbolic or hard links would confuse them.
Crypter
Crypter
#pragma once is not guaranteed to be supported on all compiliers. Thus I personally use inclusion guards.
daviangel
daviangel
Quote:
Original post by Crypter
#pragma once is not guaranteed to be supported on all compiliers. Thus I personally use inclusion guards.

Yup that was my understanding and so I see inclusion guards being used in any books that are trying to be portable like Stroustroup's.
I just finished reading Horton's book on Visual Studio and he uses #pragma once all through the book and even admits it may not work on all compilers but still uses it since that's what Visual Studio uses. Personally, I use #pragma once if I can get away with it since I'm a lazy programmer and it's less typing;)

p.s. Actually, if you are using any of the various Microsoft wizards to generate MFC programs or something else it will automatically stick #pragma once in your header files for you!


[Edited by - daviangel on September 28, 2008 5:14:19 PM]
[size="2"]Don't talk about writing games, don't write design docs, don't spend your time on web boards. Sit in your house write 20 games when you complete them you will either want to do it the rest of your life or not * Andre Lamothe
Promit
Promit
Quote:
Original post by SiCrane
Quote:
Original post by Promit
Pragma once will never hurt.

Unless your code is compiled by an older version of gcc or LCC, both of which have had buggy implementation of pragma once such symbolic or hard links would confuse them.
Although it seems odd to have symlinks or hardlinks involved, I suppose that's a fair enough reason otherwise.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Noods
Noods
Thanks for everyone's input!
CmpDev
CmpDev
Personally I use include guards as they will work anywhere, in contrast a pragma once(without a surrounded define) can do anything. If you want to write portable code then uses defines if on the other hand you are looking to try and reduce compile times then there are a couple of comparisons to note like Experiments With Includes and Even More Experiments with Includes

Granted this is for VS 2005 and not 2008, but Noel concludes ...
Quote:
Overall, there should be no real difference between using internal guards and pragma directives (which happily confirms some of the measurements we had done in real code bases). So stick with internal guards, which are standard and work on any compiler, but if adding a #pragma once directive surrounded by conditionals (because it's not standard and it's not supported in all the compilers) in addition to the internal guards would make you sleep better, go for it. External guards might have an edge with Visual Studio, but the pain and potential trouble of using external guards clearly outweighs any speed benefits gained by using them.
SiCrane
SiCrane
Quote:
Original post by Promit
Although it seems odd to have symlinks or hardlinks involved, I suppose that's a fair enough reason otherwise.

The one way I've seen is that some people deal with library versioning by creating a directory foo-x.y.z and then symlinking /usr/include/foo to foo-x.y.z, the theory being that if you need access to a specific version it's there, but for most users you just #include . I don't work on a lot of *nix boxes so I'm not sure how common a practice this is. Fortunately, versions of gcc that exhibit this bug are quite rare nowadays.
brasslips2
brasslips2
So I've done a lot of reading up on this topic. #pragma once is good because it is a higher level command than include guards. So in compilers that accept it it's better to use it. However not all compilers can recognize #pragma once but if you compile both pragma once and code guards you get the best of both worlds. You get the speed of pragma once if it will work and you also get the reliability of code guards if the compiler cannot accept pragma once. Using both works great and doesn't confuse the compiler as someone above stated. If you don't believe me here's an example http://en.wikipedia.org/wiki/Pragma_once This demonstrates with an example of what I just said:)
Way Walker
Way Walker
Are include guards common enough that one could expect the compiler to recognize them as being equivalent to #pragma once? Similar to the advice on the following producing the same code (assuming i is an int):
i = i + 1;
i += 1;
i++;
++i;
SiCrane
SiCrane
Yes, some compilers detect the use of include guards and treat them as they would a pragma once.
RobTheBloke
RobTheBloke
Quote:
Original post by Evil Steve
Include guards. I really doubt that the time saved by using #pragma once will be noticible. If in doubt, you can always use both to get the best of both worlds.


It can make a noticable difference on fairly large builds, It certainly shaved a few mins off the build time on one of our larger libs..... As a rule i always use both now....
greenhybrid
greenhybrid
Above arguments against #pragma once: word.

More generally, #pragma is the thing where a compiler-developer is allowed to implement compiler-specific stuff (e.g. to code a function without prolog/epilog when doing inline assembly). And from my own experience, *relying* on compiler specific stuff is a Bad Thing, and sooner or later you will be doomed. (most of my code that i have written in the old days is no more usable because I did know VSCPP much, but std-c++ not.)

If you know what is blessed by the c++ standard and what not, then you might also use compiler-specifics, if and only if you provide a really portable alternative (by using #ifdef-combos, which are ugly in C++; there's [0] a fine list of #define-constants, for things "#ifdef _CRAYC"), OR you know that the non-support of the #pragma in use doesn't change the behaviour (wrt output) of your program (like with OpenMP [1]).

Or accept the fact that your program will eventually only ever run on [a specific version of] Compiler X, or OS Y, or both.

[0] - http://predef.sourceforge.net/
[1] - http://openmp.org/wp/
Yann L
Yann L
Quote:
Original post by greenhybrid
Or accept the fact that your program will eventually only ever run on [a specific version of] Compiler X, or OS Y, or both.

Incorrect, at least for pragma once. If you'd argue like this, you couldn't use any kind of language extension - that means no extended calling conventions, no DLLs, no intrinsics, etc. Which is obviously nonsense.

This pragma is well established and will not go away. Using it on any halfway modern compiler is perfectly safe and will always be. And of course this is strictly a compiler issue and has nothing to do with the OS at all. All major OS (including consoles) have compilers that support pragma once just fine.
greenhybrid
greenhybrid
Quote:
Original post by Yann
If you'd argue like this, you couldn't use any kind of language extension - that means no extended calling conventions, no DLLs, no intrinsics, etc. Which is obviously nonsense.


Quote:
Original post by geenhybrid
Or accept the fact that your program will eventually only ever run on [a specific version of] Compiler X, or OS Y, or both.


*sigh*
Where is my statement wrong? Probability is still not a guarantee.

E.g. DLLs: Well, there are no Windows-DLLs in the Non-Windows-World, so it is provably fact that with dllexport your program will currently not run on Non-Windows, hence you have to accept the fact that your program will eventually only ever run on [...] a Windows-like operating system. See, I haven't referenced to the predef-sourceforge page without a reason.

Same with intrinsics: Ever seen a program running on a RISC machine that uses x86-instructions? This is where I said: Either accept inportability or provide an alternative. Isn't it true that a program that strictly follows the C++-Standard will be compilable with any conforming C++-Compiler on any platform/arch.?

I don't say "don't use this, don't use that", I say: Use it, but either provide a portable alternative (see, it has a reason why I posted an uri to predef.sf.net), or accept the fact that yada, yada.

btw, p.m.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.