pragma once
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 improvement in compilation speed.[1]
Example
- File "grandparent.h"
#pragma once
struct foo
{
int member;
};
- File "parent.h"
#include "grandparent.h"
- File "child.c"
#include "grandparent.h"
#include "parent.h"
In this example, the inclusion of grandparent.h
in both parent.h
and child.c
would ordinarily cause a compilation error, because a struct with a given name can only be defined a single time in a given compilation. The #pragma once
directive serves to avoid this by ignoring subsequent inclusions of grandparent.h
.
Advantages
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. For example,
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
... contents of grandparent.h
#endif /* !GRANDPARENT_H */
This is more complicated, possibly less efficient, and 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. 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
. Yet, since include guards appear very often and the overhead of opening files is significant, it's common for compilers to optimize the handling of include guards, making them as fast as #pragma once
.[2][3][4]
Caveats
Identifying the same file on a file system is not a trivial task.[5] Symbolic links and especially hard links may cause the same file to be found under different names in different directories. Compilers may use a heuristic that compares file size, modification time and content.[6] Additionally, #pragma once
can do the wrong thing if the same file is intentionally copied into several parts of a project, e.g. when preparing the build. Whereas include guards would still protect from double definitions, #pragma once
may or may not treat them as the same file in a compiler-dependent way. These difficulties, together with difficulties related to defining what constitutes the same file in the presence of hard links, networked file systems etc. so far prevented the standardization of #pragma once
.
Portability
Compiler | #pragma once |
---|---|
Clang | Supported[7] |
Comeau C/C++ | Supported[8] |
Cray C and C++ | Unsupported as of version 8.6[9] |
C++Builder XE3 | Supported[10] |
Digital Mars C++ | Supported[11] |
GCC | Supported[12] (since 3.4[5]) |
HP C/aC++ | Supported (since at least A.06.12) |
IBM XL C/C++ | Supported[13] (since 13.1.1) |
Intel C++ Compiler | Supported[14] |
Microsoft Visual C++ | Supported[15][16] (since 4.2) |
Pelles C | Supported[17] |
ARM DS-5 | Supported[18] |
IAR C/C++ | Supported[19] |
Keil CC 5 | Supported[20] |
Oracle Developer Studio C/C++ | Supported[21] (since 12.5) |
Portland Group C/C++ | Supported[22] (since at least 17.4) |
TinyCC | Supported[23] (since April 2015) |
References
- ↑ "Games from Within: Even More Experiments with Includes". Web.archive.org. 2005-01-25. Archived from the original on September 30, 2008. Retrieved 2013-08-19.
- ↑ "The C Preprocessor: 1. The C Preprocessor". Gcc.gnu.org. 1996-02-01. Retrieved 2013-08-19.
- ↑ ""Clang" CFE Internals Manual — Clang 3.4 documentation". Clang.llvm.org. Retrieved 2013-08-19.
- ↑ "clang: File manipulation routines". Clang.llvm.org. Retrieved 2013-08-19.
- 1 2 "GCC 3.4 Release Series — Changes, New Features, and Fixes". Gcc.gnu.org. Retrieved 2013-08-19.
- ↑ "should_stack_file() function in GCC source code".
- ↑ "clang: clang: Pragma.cpp Source File". Clang.llvm.org. Archived from the original on 2014-04-04. Retrieved 2013-08-19.
- ↑ "Comeau C++ Pre-Release User Documentation: Pragmas". Comeaucomputing.com. Retrieved 2013-08-19.
- ↑ "Cray C and C++ Reference Manual (8.6) S-2179". Cray Inc. 2018-04-17. Retrieved 2018-04-19.
- ↑ "#pragma once - RAD Studio XE3". Docwiki.embarcadero.com. 2010-12-02. Retrieved 2013-08-19.
- ↑ "Pragmas". Digital Mars. Retrieved 2013-08-19.
- ↑ "Alternatives to Wrapper #ifndef". Gcc.gnu.org. Retrieved 2013-08-20.
- ↑ "Supported GCC pragmas". IBM. Retrieved 2015-02-20.
- ↑ "Diagnostic 1782: #pragma once is obsolete. Use #ifndef guard instead". Intel Developer Zones. Retrieved 4 December 2013.
- ↑ "once (C/C++)". Msdn.microsoft.com. Archived from the original on 2016-08-10. Retrieved 2013-08-19.
- ↑ https://msdn.microsoft.com/en-us/library/4141z1cx.aspx
- ↑ IDE help/documentation
- ↑ "ARM Information Center". ARM. Retrieved 2013-12-17.
- ↑ "IAR C/C++ Development Guide" (PDF). IAR Systems. Archived from the original (PDF) on 16 May 2017. Retrieved 4 December 2013.
- ↑ "Pragmas recognized by the compiler". Keil.
- ↑ "Oracle® Developer Studio 12.5: GCC Compatibility Guide". Oracle. Retrieved 2016-07-26.
- ↑ "The Portland Group". Retrieved 31 July 2016.
- ↑ "TinyCC pragma once implementation". Retrieved 19 June 2018.