pragma once

From Wikipedia, the free encyclopedia
Jump to: navigation, search
The correct title of this article is #pragma once. The substitution or omission of the # is because of technical restrictions.

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, avoidance of name clashes, and sometimes improved compile speed.[1]

Example[edit]

File "grandparent.h"
#pragma once
 
struct foo 
{
    int member;
};
File "parent.h"
#include "grandparent.h"
File "child.c"
#include "grandparent.h"
#include "parent.h"

Advantages[edit]

The most common alternative to #pragma once is to use #define to set an include guard macro, the name of which is picked by the programmer to be unique to that file. This is very much prone to error as there are no mechanisms to prevent a programmer accidentally using the same macro name in more than one file, which would result in only one of the files being included. This problem renders #pragma once to be advantageous. Since the compiler itself is responsible for handling #pragma once, the programmer cannot make errors which cause name clashes.

Using #pragma once instead of include guards will, for some compilers, improve 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. It is important to note that some compilers such as GCC, Clang, and EDG-based compilers include specific optimizations 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][4]

Caveats[edit]

Identifying the same file on a file system is not a trivial task.[5] Symbolic links and hard links may cause the same file to be found under different names. Compilers may use a heuristic that compares file size, modification time and content.[6] This backfires when the same file is intentionally copied into several parts of a project. With include guard based on file path these copies would be treated differently while #pragma once will randomly treat them as the same file in a compiler-dependent way.

Portability[edit]

Compiler #pragma once
Clang Supported[7]
Comeau C/C++ Supported[8]
C++Builder XE3 Supported[9]
Digital Mars C++ Supported[10]
GCC Supported[11] (since 3.4[5])
Intel C++ Compiler Supported[12]
Microsoft Visual C++ Supported[13]
Pelles C Supported[14]
ARM DS-5 Supported[15]
IAR C/C++ Supported[16]

References[edit]

  1. ^ "Games from Within: Even More Experiments with Includes". Web.archive.org. 2005-01-25. Retrieved 2013-08-19. 
  2. ^ "The C Preprocessor: 1. The C Preprocessor". Gcc.gnu.org. 1996-02-01. Retrieved 2013-08-19. 
  3. ^ ""Clang" CFE Internals Manual — Clang 3.4 documentation". Clang.llvm.org. Retrieved 2013-08-19. 
  4. ^ "clang: File manipulation routines". Clang.llvm.org. Retrieved 2013-08-19. 
  5. ^ a b "GCC 3.4 Release Series — Changes, New Features, and Fixes". Gcc.gnu.org. Retrieved 2013-08-19. 
  6. ^ "should_stack_file() function in GCC source code". 
  7. ^ "clang: clang: Pragma.cpp Source File". Clang.llvm.org. Retrieved 2013-08-19. 
  8. ^ "Comeau C++ Pre-Release User Documentation: Pragmas". Comeaucomputing.com. Retrieved 2013-08-19. 
  9. ^ "#pragma once - RAD Studio XE3". Docwiki.embarcadero.com. 2010-12-02. Retrieved 2013-08-19. 
  10. ^ "Pragmas". Digital Mars. Retrieved 2013-08-19. 
  11. ^ "Alternatives to Wrapper #ifndef". Gcc.gnu.org. Retrieved 2013-08-20. 
  12. ^ "Diagnostic 1782: #pragma once is obsolete. Use #ifndef guard instead.". Intel Developer Zones. Retrieved 4 December 2013. 
  13. ^ "once (C/C++)". Msdn.microsoft.com. Retrieved 2013-08-19. 
  14. ^ IDE help/documentation
  15. ^ "ARM Information Center". ARM. Retrieved 2013-12-17. 
  16. ^ "IAR C/C++ Development Guide". IAR Systems. Retrieved 4 December 2013.