#pragma once VS #ifndef _FOO_H_

Started by
8 comments, last by Rob Loach 20 years, 5 months ago
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]
Rob Loach [Website] [Projects] [Contact]
Advertisement
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.
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_ */
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
quote:Original post by LessBread
...brillance...


Thanks a lot LessBread.

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
Rob Loach [Website] [Projects] [Contact]
Which compilers support #pragma once?

--
AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
[Project site] [Blog] [RSS] [Browse the source] [IRC channel]
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
I''ve always wondered what the point is of using both include guards and #pragma once.
quote:Original post by Arild Fines
Which compilers support #pragma once?


I know the Microsoft ones support it, but gcc flags it as obsolete IIRC.
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 ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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...#endifb.hpp#ifndef B_HPP#define B_HPP#include "a.hpp"...#endifc.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...#endifb.hpp#ifndef B_HPP#define B_HPP#ifndef A_HPP#include "a.hpp"#endif...#endifc.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.
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.

This topic is closed to new replies.

Advertisement