once pragma
Specifies that the compiler includes the header file only once, when compiling a source code file.
Syntax
Remarks
The use of #pragma once can reduce build times, as the compiler won’t open and read the file again after the first #include of the file in the translation unit. It’s called the multiple-include optimization. It has an effect similar to the include guard idiom, which uses preprocessor macro definitions to prevent multiple inclusions of the contents of the file. It also helps to prevent violations of the one definition rule: the requirement that all templates, types, functions, and objects have no more than one definition in your code.
// header.h #pragma once // Code placed here is included only once per translation unit
We recommend the #pragma once directive for new code because it doesn’t pollute the global namespace with a preprocessor symbol. It requires less typing, it’s less distracting, and it can’t cause symbol collisions. Symbol collisions are errors caused when different header files use the same preprocessor symbol as the guard value. It isn’t part of the C++ Standard, but it’s implemented portably by several common compilers.
There’s no advantage to use of both the include guard idiom and #pragma once in the same file. The compiler recognizes the include guard idiom, and implements the multiple-include optimization the same way as the #pragma once directive if no non-comment code or preprocessor directive comes before or after the standard form of the idiom:
// header.h // Demonstration of the #include guard idiom. // Note that the defined symbol can be arbitrary. #ifndef HEADER_H_ // equivalently, #if !defined HEADER_H_ #define HEADER_H_ // Code placed here is included only once per translation unit #endif // HEADER_H_
We recommend the include guard idiom when code must be portable to compilers that don’t implement the #pragma once directive, to maintain consistency with existing code, or when the multiple-include optimization is impossible. It can occur in complex projects when file system aliasing or aliased include paths prevent the compiler from identifying identical include files by canonical path.
Be careful not to use #pragma once or the include guard idiom in header files designed to be included multiple times, that use preprocessor symbols to control their effects. For an example of this design, see the header file. Also be careful to manage your include paths to avoid creating multiple paths to included files, which can defeat the multiple-include optimization for both include guards and #pragma once .
once pragma
Указывает, что компилятор включает файл заголовка только один раз при компиляции файла исходного кода.
Синтаксис
Remarks
Использование может сократить время сборки #pragma once , так как компилятор не открывает и не считывает файл снова после первого #include файла в блоке преобразования. Она называется оптимизацией с несколькими включениями. Он имеет эффект, аналогичный идиоме include guard , которая использует определения макросов препроцессора для предотвращения множественных включений содержимого файла. Это также помогает предотвратить нарушения одного правила определения: требование, чтобы все шаблоны, типы, функции и объекты имели не более одного определения в коде.
// header.h #pragma once // Code placed here is included only once per translation unit
Мы рекомендуем директиву #pragma once для нового кода, так как она не засоряет глобальное пространство имен символами препроцессора. Он требует меньше ввода, меньше отвлекает и не может вызвать конфликт символов. Конфликты символов — это ошибки, вызванные тем, что разные файлы заголовков используют один и тот же символ препроцессора, что и значение guard. Она не является частью стандарта C++, но реализована несколькими распространенными компиляторами.
Использование идиомы include guard и #pragma once одного файла не имеет никакого преимущества. Компилятор распознает идиому включения и реализует оптимизацию с несколькими включателями так же, как #pragma once и директива , если ни один некомментированный код или директива препроцессора не поступают до или после стандартной формы идиомы:
// header.h // Demonstration of the #include guard idiom. // Note that the defined symbol can be arbitrary. #ifndef HEADER_H_ // equivalently, #if !defined HEADER_H_ #define HEADER_H_ // Code placed here is included only once per translation unit #endif // HEADER_H_
Рекомендуется использовать идиому включения, если код должен быть переносим в компиляторы, которые не реализуют директиву #pragma once , для обеспечения согласованности с существующим кодом или когда оптимизация с несколькими включающими невозможна. Это может происходить в сложных проектах, когда псевдонимы файловой системы или пути включения с псевдонимами не позволяют компилятору идентифицировать идентичные файлы включения по каноническому пути.
Будьте внимательны, чтобы не использовать #pragma once идиому или идиому включения в файлах заголовков, предназначенных для многократного включения, которые используют символы препроцессора для управления их эффектами. Пример такой схемы см. в файле заголовка . Кроме того, будьте осторожны при управлении путями включения, чтобы избежать создания нескольких путей к включенным файлам, что может помешать оптимизации с несколькими включателями как для включаемых охранников, так и #pragma once для .
once pragma
Specifies that the compiler includes the header file only once, when compiling a source code file.
Syntax
Remarks
The use of #pragma once can reduce build times, as the compiler won’t open and read the file again after the first #include of the file in the translation unit. It’s called the multiple-include optimization. It has an effect similar to the include guard idiom, which uses preprocessor macro definitions to prevent multiple inclusions of the contents of the file. It also helps to prevent violations of the one definition rule: the requirement that all templates, types, functions, and objects have no more than one definition in your code.
// header.h #pragma once // Code placed here is included only once per translation unit
We recommend the #pragma once directive for new code because it doesn’t pollute the global namespace with a preprocessor symbol. It requires less typing, it’s less distracting, and it can’t cause symbol collisions. Symbol collisions are errors caused when different header files use the same preprocessor symbol as the guard value. It isn’t part of the C++ Standard, but it’s implemented portably by several common compilers.
There’s no advantage to use of both the include guard idiom and #pragma once in the same file. The compiler recognizes the include guard idiom, and implements the multiple-include optimization the same way as the #pragma once directive if no non-comment code or preprocessor directive comes before or after the standard form of the idiom:
// header.h // Demonstration of the #include guard idiom. // Note that the defined symbol can be arbitrary. #ifndef HEADER_H_ // equivalently, #if !defined HEADER_H_ #define HEADER_H_ // Code placed here is included only once per translation unit #endif // HEADER_H_
We recommend the include guard idiom when code must be portable to compilers that don’t implement the #pragma once directive, to maintain consistency with existing code, or when the multiple-include optimization is impossible. It can occur in complex projects when file system aliasing or aliased include paths prevent the compiler from identifying identical include files by canonical path.
Be careful not to use #pragma once or the include guard idiom in header files designed to be included multiple times, that use preprocessor symbols to control their effects. For an example of this design, see the header file. Also be careful to manage your include paths to avoid creating multiple paths to included files, which can defeat the multiple-include optimization for both include guards and #pragma once .
Pragma Once in C++
This article begins with an overview of pragma once as a preprocessor directive and a simple example of how it is used. After this, we will cover a few specific properties of pragma once regarding its support in C and C++, and lastly, we will include a more holistic example of how it can be used and how it is better than its alternatives.
Pragma Once in C++
pragma once is used in C and C++ as a preprocessor directive. Preprocessor directives are single-line pieces of code that do not make up the program and are read by the preprocessor instead.
The preprocessor analyzes these before the compilation of the code. The preprocessor does not expect a semi-colon at the end of these directives either.
Hence, to add the pragma once directive to your code, add the following to the top of the file.
pragma once itself is non-standard. This means that some compilers will not support it, and due to its complex implementation, it might not always be reliable.
However, it is very commonly supported; hence in most cases, using pragma once should not be a problem. Its purpose is simple: it ensures that the current source file (the file in which the directive is being written) is only included once in the compilation.
This job can be done alternatively using include guards. We will discuss the differences after an example of how pragma once is used.
pragma once is primarily used when defining classes. In the following example, we will define two classes: Structure and Room .
The Room class will inherit from the Structure class.
// This contains the code for the Structure class // Save this as Structure.h #pragma once #include #include using namespace std; class Structure string struc_name; int id; public: void setVals() struc_name = "Example Name"; id = 1; > void printVals() cout <"Name is: " <" and id is: " > >;
We will now define the Room class.
// Save this as Room.h #pragma once #include "Structure.h" class Room Structure example; public: void initRoom() example.setVals(); > void getRoom() example.printVals(); > >;
We can now define a main function that uses the above objects.
// save this in a main.cpp file #include "Structure.h" #include "Room.h" #include using namespace std; int main() Room testRoom; testRoom.initRoom(); testRoom.getRoom(); return 0; >
In the above example, if we run the code, we get Name is: Example Name and id is: 1 as the output, which is what we expect. However, if we remove the pragma once , we get the following errors.
In file included from Room.h:3, from main.cpp:2: Structure.h:8:7: error: redefinition of 'class Structure' 8 | class Structure | ^~~~~~~~~ In file included from main.cpp:1: Structure.h:8:7: note: previous definition of 'class Structure' 8 | class Structure | ^~~~~~~~~
The class Structure is defined twice. Using pragma once , we can ensure that it is only read once.
The alternative is to use identifiers instead. In the context of the above example, we can do it as defined below.
#ifndef STRUCTURE #define STRUCTURE class Structure // Some sample code here >; #endif
In the above example, STRUCTURE can be replaced with anything. However, we normally keep the name as something that corresponds to the class’s name.
However, there are possible issues here. Firstly, it is more verbose, requires manual decision-making, and the compiler has no protection from the programmer accidentally using the macro name somewhere else in the project.
Compilers are usually optimized for pragma once increasing compilation speed.
Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.