|
|
This article has multiple issues. Please help improve it or discuss these issues on the talk page.
|
In the C and C++ programming languages, #pragma once is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once serves the same purpose as #include guards, but with several advantages, including: less code, avoiding name clashes, and sometimes improved compile speed.[1]
See the article on #include guards for an example of a situation in which one or the other of these methods must be used. The solution using include guards is given on that page; the #pragma once solution would be:
- File "grandparent.h"
#pragma once struct foo { int member; };
- File "parent.h"
#include "grandparent.h"
- File "child.c"
#include "grandparent.h" #include "parent.h"
|
Contents
|
Advantages and disadvantages
Using #pragma once instead of include guards will typically increase compilation speed since it is a higher-level mechanism; the compiler itself can compare filenames or inodes without having to invoke the C preprocessor to scan the header for #ifndef and #endif.
Some compilers such as GCC, Clang, and EDG-based compilers include special speedup code to recognize and optimize the handling of include guards, and thus little or no speedup benefit is obtained from the use of #pragma once.[2][3]
Again because the compiler itself is responsible for handling #pragma once, it is not necessary for the programmer to create new macro names such as GRANDPARENT_H in the Include guard article's example. This eliminates the risk of name clashes, meaning that no header file can fail to be included at least once.
However, this high-level handling is not perfect; the programmer must rely on the compiler to handle #pragma once correctly. If the compiler makes a mistake, for example by failing to recognize that two symbolic links with different names point to the same file, then the compilation will fail. Compilers with #pragma once-related bugs included LCC-Win32 as of 2004[update] [4][5] and GCC as of 1998[update].[6] GCC originally gave a warning declaring #pragma once "obsolete" when compiling code that used it. However, with the 3.4 release of GCC, the #pragma once handling code was fixed to behave correctly with symbolic and hard links. The feature was "un-deprecated" and the warning removed.[7][8]
Both #pragma once and include guards can be used to write portable code that can also take advantage of #pragma once optimizations the compiler may support:
- File "grandparent.h"
#pragma once #ifndef GRANDPARENT_H #define GRANDPARENT_H struct foo { int member; }; #endif /* GRANDPARENT_H */
Portability
| Compiler | #pragma once |
|---|---|
| Clang | Supported[9] |
| Comeau C/C++ | Supported[10] |
| Digital Mars C++ | Supported[11] |
| GCC | Supported[12] |
| Intel C++ Compiler | Supported[13] |
| Microsoft Visual Studio | Supported[14] |
Notes
- ^ http://web.archive.org/web/20080930061318/http://www.gamesfromwithin.com/articles/0501/000067.html
- ^ http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8
- ^ http://clang.llvm.org/docs/InternalsManual.html#MultipleIncludeOpt
- ^ http://groups.google.com/groups?selm=bvjqhn$q5o$1@news-reader1.wanadoo.fr
- ^ http://groups.google.com/groups?selm=488cbfe1.0304061213.264d94d@posting.google.com
- ^ http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8
- ^ http://gcc.gnu.org/onlinedocs/gcc-4.0.3/cpp/Obsolete-once_002donly-headers.html#Obsolete-once_002donly-headers
- ^ http://gcc.gnu.org/gcc-3.4/changes.html
- ^ http://clang.llvm.org/doxygen/Pragma_8cpp-source.html#l00184
- ^ http://www.comeaucomputing.com/4.0/docs/userman/pragma.html
- ^ http://www.digitalmars.com/ctg/pragmas.html#once
- ^ http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Alternatives-to-Wrapper-_0023ifndef.html
- ^ http://secure-software.intel.com/en-us/articles/cdiag1782/#comment-9466
- ^ http://msdn.microsoft.com/en-us/library/4141z1cx.aspx
External links
This entry is from Wikipedia, the leading user-contributed encyclopedia. It may not have been reviewed by professional editors (see full disclaimer)




