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
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 <iostream>
#include <string>
using namespace std;
class Structure {
string struc_name;
int id;
public:
void setVals() {
struc_name = "Example Name";
id = 1;
}
void printVals() {
cout << "Name is: " << struc_name << " and id is: " << id << endl;
}
};
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 <iostream>
#include "Room.h"
#include "Structure.h"
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.
LinkedIn