Archived

This topic is now archived and is closed to further replies.

Rob Loach

#pragma once VS #ifndef _FOO_H_

Recommended Posts

What exactly is the difference between the two following precompiler directives inside header files?: #ifndef _FOO_H_ #define _FOO_H_ /* code */ #endif ...and... #pragma once /* code */ Are they esencially the same?
Rob Loach
Website: Over-Development
Current Project: Pong, The First

"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed. "
- The Boondock Saints
[edited by - Rob Loach on November 16, 2003 3:47:33 PM]

Share this post


Link to post
Share on other sites
Not sure, but I''d think that "#pragma once" isn''t a standard thing. Functionally they should be equal, the #pragma directive created to avoid the awkward #ifndef hacks.

Of course, I might be completely wrong.

Share this post


Link to post
Share on other sites
Yes, they amount to the same thing. However, pragmas are compiler specific directives. If the compiler doesn''t recognize the pragma, it will ignore it. Preprocessor directives can''t be ignored.

The two statements aren''t mutually exclusive and can be used together like so:

#ifndef HEADER_H_
#define HEADER_H_
#pragma once

...

#endif /* HEADER_H_ */

Share this post


Link to post
Share on other sites
quote:
Original post by merlin9x9
I''ve always wondered what the point is of using both include guards and #pragma once .


Include guards guarantee your header is only included once, portably.
#pragma once guarantee your header is loaded from file only once, where supported.

It works as a compilation speed optimization (like precompiled headers) where supported..


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
It works as a compilation speed optimization (like precompiled headers) where supported..



Yes, though you can have doublefold in compilation speed if you take it extreme.

a.hpp
#ifndef A_HPP
#define A_HPP
...
#endif

b.hpp
#ifndef B_HPP
#define B_HPP
#include "a.hpp"
...
#endif

c.cpp
#include "a.hpp"
#include "b.hpp"
...


In this case, compiling c.cpp will run as follow. Detected include of a.hpp. Open a.hpp. Check if A_HPP is defined. If not defined, include the rest of the contents within the inclusion guard. Ok control flows back to c.cpp. Detected include of b.hpp. Open b.hpp. Check if B_HPP is defined. If not defined, carry on the rest of the content,and in this case, include of a.hpp is detected again. Open a.hpp. Check if A_HPP is defined. It is defined now, so skip whatever is within the inclusion guard. Go back to c.cpp and process rest of files. Notice that there is still additional file access to a.hpp even though it has been included before. So, to furthur speed stuff up,


a.hpp
#ifndef A_HPP
#define A_HPP
...
#endif

b.hpp
#ifndef B_HPP
#define B_HPP

#ifndef A_HPP
#include "a.hpp"
#endif
...
#endif

c.cpp
#ifndef A_HPP
#include "a.hpp"
#endif
#ifndef B_HPP
#include "b.hpp"
#endif
...


In this second case, compiling c.cpp will run as follow. Check if A_HPP is defined. If not, detect include of a.hpp. Open a.hpp. Check if A_HPP is defined. If not defined, include the rest of the contents within the inclusion guard. Ok control flows back to c.cpp. Check if B_HPP is defined. If not defined, carry on the rest of the content,and in this case, detected include of b.hpp. Open b.hpp. Check if B_HPP is defined. Since B_HPP is not defined yet, carry on processing. At this time, however, check if A_HPP is defined. It is defined now, so skip the file opening. Go back to c.cpp and process rest of files. In projects where you have many inclusion and slow compile time, this might help speed up compilation.

This technique is described in Lakos'' Large Scale C++ Software Design if anyone is interested.

Share this post


Link to post
Share on other sites
quote:
nclude guards guarantee your header is only included once, portably.
#pragma once guarantee your header is loaded from file only once, where supported.


Oh, of course! I''d never even though of that significant distinction. Thanks.

Share this post


Link to post
Share on other sites