pragma or ifndef? - C++ forum (2023)

Jay Gln (47)

I was finishing a test my professor gave me with just a part of the .h file to answer some multiple choice questions. I wanted to try to figure out where he was going with his code, so I decided to try to create a program that could take him to see if I start to understand what he teaches about data structures and algorithms. The problem is that now I can't even compile to test anything or go further. He taught us to use #ifndef especially in our .h in our .cpp file containing our definitions and then just #include in our main.cpp. I got a link error saying it was already defined in my obj file. I then researched how to try to fix it and found that using #pragma was cleaner and newer compilers are using it. Can anyone shed some light on what is the best practice? Is #ifndef an outdated way to check for inclusion of multiple files? Or am I doing something wrong? In the following code, I'll comment out the pragma and ifndef where I used it, just so you can see the full scope.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sixteen
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Sixty-five
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// My header file //#pragma once//#ifndef COINSORTER_H//#define COINSORTER_H#include <string>#include <iomanip>using namespacestandard;classroomcoin sorter{public:static constantstring DEFAULT_COUNTRY;// These constructors do not create any kind of currency;// setTypes() will create the currency types instead.coin sorter();// default countryCoin Sorter(constantstring &initPaís);// Copy the constructorCoin Sorter(constantcoin sorter and other sorter);// assignment operatorcoin sorter andoperator=(constantcoin sorter and other sorter);// Destructor~Coin Sorter();// Accessors and mutators//to takeAnd tgetCount(And tsay);//to addemptyaddType(And ttype);// Create all kinds of coins with space to store counts.// This function can be called more than once with// a different number of types each time.emptysetTypes(And tnovosNumTipos);private: country string;And t* account;// store dynamic array for count of each typeAnd tnumTipos;// dynamic array size};//#will end if//My .cpp definitions//#pragma once//#ifndef COINSORTER_H//#define COINSORTER_H#include <iostream>#include "Coin Sorter.h"using namespacestandard;// constructorsCoin Sorter::Coin Sorter() {country = DEFAULT_COUNTRY;} Coin Sorter::Coin Sorter(constantstring &initCountry){país = initCountry;}//copy the constructorCoin Sorter:: Coin Sorter (constantCoin sorter and other sorter){// copy non-dynamic arraynumTypes = otherSorter.numTypes;// assign the new arrayaccount =nuevo And t[numTipos];// copy non-dynamic arrayfor(And ti = 0; i < numTypes; i++){accounts[i] = otherClassifier.accounts[i];}}// mnet operator assignmentCoin Sorter and Coin Sorter::operator=(constantCoin sorter and other sorter){con(to be!= &otherClassifier){// evictdelete[] account;//to distributenumTypes = otherSorter.numTypes;// assign the sizeaccount =nuevo And t[numTipos];for(And ti = 0; i < otherClassifier.numTypes; i++){accounts[i] = otherClassifier.accounts[i];}}return*to be;}//destructorCoin Sorter::~ Coin Sorter(){delete[] count;count = NULL;numTypes = 0;}And tCoin Sorter::getCount(And tsay){returnTell me tell me];}emptyCoin classifier::addType(And ttype){And tUE;for(i = 0; i < numTipos; i++){con(account[i] ==And t()){account[i] = type;return;}}}// Accessors and mutators// Create all kinds of coins with space to store counts.// This function can be called more than once with// a different number of types each time.emptyCoin classifier::setTypes(And tnewNumTypes){numTypes = newNumTypes;contagens =nuevo And t[novoNumTipos];}//#will end if// My main//#pragma once////#include <iostream>#include <string>#include "Coin Classifier.cpp"using namespacestandard;And tprincipal(){constant And tTYPES = 3;//types is the currency itselfCoinSorter france("France");france.setTypes(TIPOS);for(And ti = 0; i < TYPES; i++){france.addType(TYPES + i);}for(And tyo = 0; i < TIPOS; i++){cout << frança.getCount(i);}return0;}

Last edition on

closed account (z05DSL3A)

If I'm reading your code correctly, don't use import guards in your cpp files, just their headers.

Can anyone shed some light on what is the best practice? Is #ifndef an outdated way to check for inclusion of multiple files?

I don't know the best practices, but I tend to use both at the same time. There is a slight difference between the two, but it is hardly noticeable. using both means that if the compiler doesn't understand the pragma once, it will fall back to the venerable ifndef.

Last edition on

closed account (E0p9LyTq)

#pragma is not standard, not all compilers support it.

(Video) C++ Basics For Beginners :: Header Files :: pragma once vs ifndef

Every compiler worth using understands the #ifndef/#define/#endif header guards.

Header protectors, as the name implies, should only be used on header files. Never in .c/.cpp source files.

AbstractionAnon (6931)

Line 174: Must include cosorter.h, not consorter.cpp. NEVER include a .cpp file. This will give you duplicate set symbols at link time.

As for #pragma once, #ifndef verses, I prefer #pragma once because I think the cleaner and all the compilers I work with support it. However, as already noted, not all compilers support #pragma once.

mbozzi (3759)

About

#pragma once

against include guards:

It's probably obvious that the former is easier to write. While it's not part of the C++ standard, it's ubiquitous nonetheless.

However,

once

it has a subtle drawback in that it depends on the implementation's interpretation of the file's identity. For example, if a source file is copied or linked, it is not clear whether or not the copy (or link) refers to the same file and must be included twice. Include protectors avoid this problem by associating a unique ID with the file.content.

IIRC, the question offile identityit's part of the reason this pragma (or an equivalent feature) was never standardized. If you're not doing weird stuff with your source files, it probably doesn't matter.

(I prefer to include guards, despite the increased chance of typos.)

Last edition on

Angry (1340)

Last edition on

(Video) How to Include File Guards - Why to Include Fileguards in C or C++ Header Files

average (10294)

Line 174: Must include cosorter.h, not consorter.cpp. NEVER include a .cpp file. This will give you duplicate set symbols at link time.

The problem is that when you give the compiler a file (let's call it X), the compiler runs the preprocessor on X.
The preprocessor essentially finds the "header file" mentioned in '#include' and copies and pastes it into X instead of the include.
Those headers probably include something too, so the preprocessor iterates "recursively" until (copy of) X (in memory) is all code and not #***.

Include protections (pragma or ifndef) prevent the preprocessor from copying and pasting multiple code copies of the same header file into X. Without protections, repetition will be seen by the compiler as a fatal error.

Finally, the compiler compiles the X code into the object file. There may be more than one file to compile.
The linker combines object files into executables.

An IDE/build system probably compiles all .cpp files in the project by default.
The convention is that you want one object file for each .cpp file.

If your build system compiles bothcpp classifiermiprincipal.cppseparately and main.cpp includes code from coinSorter.cpp, so the object file generated from main.cpp contains the same instructions as the object file created from coinSorter.cpp. Repeated "symbols" will be seen by the linker as a fatal error.

IF you NEVER include a .cpp file, THEN it follows the convention and is less buggy.

Use the pattern, follow the convention.

Juan (11159)

(Video) C++ Header Files

the only pragmas you should use are to do things you can't do otherwise (like disabling bogus 'deprecation' of legitimate C++ code in M$). Do not use them to include guards or normal buildings.

JLBorges (13725)

> Can anyone clarify what the best practice is?

Both have advantages and disadvantages.

#pragma once

It's not standard, but it's supported by all major C++ compilers.

Unlike header protectors, this pragma makes it impossible to mistakenly use the same macro name in more than one file. On the other hand, as with #pragma, once files are excluded based on their identity at the filesystem level, this does not protect against including a header twice if it exists in more than one place in a file. project.
https://en.cppreference.com/w/cpp/preprocessor/impl

We can use both if we want. For example:

1
2
3
4
5
6
7
8
9
#pragma once#ifndef MY_HEADER_H_INCLUDED#define MY_HEADER_H_INCLUDED// ...#end if// MY_HEADER_H_INCLUDED

Last edition on

closed account (E0p9LyTq)

Can anyone shed some light on what is the best practice?

There will be people on both sides who will fight to the digital death for its proper use as sacred scripture.

(Video) C++ Header Guards

Jay Gln (47)

Thank you all for shedding some light on this matter. AbstractionAnon I include the header file inside the .cpp definition file and then I include that cpp file in my main file because that's how my teacher showed it to me. It said that by including the cpp file inside my main file, the header file will automatically come with it as it is included in the definition cpp file. Now that you mention it, I'll try it the way you suggest, but I may still have to do it my way during class. I have another question that I'd love to hear about: I'm not one to create clever programs to write myself. But people talk about sites to access that offer problems to work, like Odin, codeingames3 or code chef. Do you know of others who help with algorithms?

Two meters (12987)

It's funny how these threads reappear with such regularity.

#pragma onceit was already very popular. It is still supported by all modern compilers.

Also, all modern compilers do this.even without him#pragma onceguide.

The problem
Pragma once / filename tracking can be overridden. This is not an abstract problem, but an obvious one.

The bottom line is that it is easily possible to produce multiple names for a single file. Or to duplicate the contents of a file in another location.

Very large systems with hundreds of developers.dofight these problems.

The only solution that can't be beat
...stay using include guards, if donecorrectly.

Because you can still screw it up. The first is pretty obvious: you can pick a silly name that conflicts with another library, likeSTRING_H. This isn't so bad, except that it easily leads to the second problem:

Identical libraries withdifferentinclude guards.

better practices
Always always,Alwaysuse includes guards. Make your include protections unique,when you create the file for the first time. Personally, I use something that cannot be confused:

1
2
3
4
5
6
7
8
9
10
#ifndef DUTHOMHAS_STRING_HELPERS_201903121140_HPP#define DUTHOMHAS_STRING_HELPERS_201903121140_HPPnamespacetwo slashes {...}#end if

Yes. This is the date I first created, including the protection/library file, encoded along with my unique name and file function.

This will never conflict with someone else's library (unless the conflict is intentional). No matter how the file/content/whatever is duplicated, single include protection is loaded along with it.

The next point is also essential: when available, keep everything in a proper namespace.
The inclusion of guards protects against multiple identical symbols when compiling; namespaces protect against multiple identical symbols whenvocation.

If, in addition, you want to add the

#pragma once

directive, there is no good reason not to do so. (This can break automatic detection for an existing compiler, but as already mentioned, modern compilers can handle this with grace. Those that can't fall back on include protection, as designed.)

So don't be surprised to find:

1
2
3
# include once#ifndef MYFOO_ALGO_ÚNICO_HPP#define MYFOO_SOMETHING_UNIQUE_HPP
(Video) Precompiled Headers in C++

Perfectly acceptable. Guaranteed not to break -but only due to single include protection.

However, as recommended by the ISO committee, the use of#pragma oncenow it's more of a crutch than useful. I think it is well recommended.discontinue use. Again, all modern compilers already perform their function regardless of whether they are present or not.

Use exclusive include protectors. Please don't do otherwise.

FAQs

Is pragma once better than Ifndef? ›

One alleged advantage of #pragma once is that it can be faster, since the preprocessor doesn't need to read the entire file to find a matching #endif for the #ifndef directive. The file contents can be skipped at an earlier stage. However, these claims are hard to reproduce with modern compilers and practical examples.

Is pragma once enough? ›

Do not use #pragma once; instead use the standard Google include guards. The path in the include guards should be relative to the top of your project tree.

When should I use Ifndef? ›

#ifndef is often used to make header files idempotent by defining a token once the file has been included and checking that the token was not set at the top of that file.

Why avoid pragma once? ›

Since the macros that guard each file have the same name, the header guards will work perfectly fine and only include one file. Since, from the FS point of view, files are different, #pragma once will behave as if they are different file, and thus include each file separately. This leads to a compilation error.

Is pragma once faster? ›

By contrast, #pragma once only checks whether files are physically the same (it doesn't open file). Therefore, #pragma once runs faster than include guard in the compilation phase.

Should I use pragma once or header guards? ›

#pragma once reduces possibilities for bugs.

It is all too easy to copy and paste a header file to another header file, modify it to suit ones needs, and forget to change the name of the include guard. Once both are included, it takes you a while to track down the error, as the error messages aren't necessarily clear.

Where should I use pragma once? ›

Description. #pragma once is a preprocessor directive used to prevent header files from being included multiple times. The #pragma once directive, once present in a file, assures that the file will not be included multiple times in the current project.

Why do we use Pragma instead of include guard? ›

In the absence of #include guards around #include directives, the use of #pragma once will improve compilation speed for some compilers 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 .

Is pragma once standard now? ›

#pragma once is a non-standard pragma that is supported by the vast majority of modern compilers. If it appears in a header file, it indicates that it is only to be parsed once, even if it is (directly or indirectly) included multiple times in the same source file.

What's the purpose of the Ifndef test? ›

The #ifndef conditional test checks "if the symbol SOME_UNIQUE_SYMBOL is not defined. Thus, the first time that the preprocessor comes across the #ifndef SOME_UNIQUE_SYMBOL directive, the symbol will not be defined, and thus, the body of the directive (up to #endif) will be included in the file sent to the compiler.

What is the use of Ifndef in C programming? ›

The #ifndef directive is one of the widely used used directives in C. It allows conditional compilations. During the compilation process, the preprocessor is supposed to determine if any provided macros exist before any subsequent code is included.

Can you use #else for #ifdef? ›

Remarks. Each #if directive in a source file must be matched by a closing #endif directive. Any number of #elif directives can appear between the #if and #endif directives, but at most one #else directive is allowed. The #else directive, if present, must be the last directive before #endif.

What is the difference between guard and pragma once in C++? ›

In addition to reducing errors, #pragma once is typically optimized to reduce the use of the preprocessor and file openings, making it faster than include guards. Note that many compilers optimize for this already, so it is possible they are equally fast.

What does #pragma once do in C++? ›

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.

What is pragma unroll? ›

The UNROLL pragma specifies to the compiler how many times a loop should be unrolled. The UNROLL pragma is useful for helping the compiler utilize SIMD instructions. It is also useful in cases where better utilization of software pipeline resources are needed over a non-unrolled loop.

What is the uses of #pragma? ›

The preprocessor directive #pragma is used to provide the additional information to the compiler in C/C++ language. This is used by the compiler to provide some special features.

What is the difference between #define and #pragma? ›

The #ifndef/#define/#endif trick works on any C compiler, and on some of them it speeds up the compilation process. The #pragma trick is non-standards, and only works on few C compilers, and may result in different semantics in those that do not support it.

Which compilers support pragma once? ›

Clang, g++, Intel C++, and Visual C++ all support #pragma once .

Should you always use header guards? ›

Header guards are designed to ensure that the contents of a given header file are not copied, more than once, into any single file to prevent duplicate definitions. This is a good thing because we often need to reference the contents of a given header from different project files.

Are header-only libraries good? ›

Benefits of header-only library: Simplifies the build process. You don't need to build the library, and you don't need to specify the compiled library during the link step of the build.

Why are header-only libraries good? ›

The benefit of header-only libraries is that they are easy to include in your project as you simply include the header and you are done (there is no need to compile the library as there are no source files to compile).

What does pragma stand for? ›

Pragma, an abbreviation for pragmatic, or from the same root, may refer to: πράγμα, the Ancient Greek word; see pragmatism. Directive (programming), also known as a pragma or pragmat in several programming languages.

Why should header files avoid having using declarations? ›

This can provoke ambiguities in client code, or even select the wrong function during overload resolution. A namespace 'using' declaration is not as polluting, but can have strange side effects since it only captures function overload sets at the time it appears.

Why use #ifndef in header files? ›

#ifndef and #define are known as header guards. Their primary purpose is to prevent C++ header files from being included multiple times.

When protecting a header file which choice is a reason to use #pragma? ›

#pragma once serves the same purpose as header guards: to avoid a header file from being included multiple times.

Which pragma is used to remove? ›

Explanation: #pragma poison GCC is used to remove an identifier from a program. It should be followed by a list of identifiers which are not valid in the program, for example: scanf, printf etc.

Why do we need include guards? ›

Include guards are used to prevent a file, actually the contents of a file, from being included more than once. The header file above has an include guard. The ifndef is an if statement. The #endif is the end of the if body.

Is pragma C++ standard? ›

Compiler pragmas are also called directives. The preprocessor keyword pragma is part of the C++ standard, but the form, content, and meaning of pragmas is different for every compiler. No pragmas are defined by the C++ standard. Code that depends on pragmas is not portable.

What is an include guard in C++? ›

In the C and C++ programming languages, an #include guard, sometimes called a macro guard, header guard or file guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.

What is the difference between Ifndef and Ifdef? ›

Use the #ifdef statement when you want to compile a section only if a specified expression has been defined with #define. Use #ifndef when you want to compile a section only if a specified expression has not been defined. // Compile if A is defined.

What does #ifdef mean in C++? ›

The #ifdef identifier statement is equivalent to #if 1 when identifier has been defined. It's equivalent to #if 0 when identifier hasn't been defined, or has been undefined by the #undef directive.

What is the purpose of Ifdef? ›

The #ifdef directive checks for the existence of macro definitions. If the identifier specified is defined as a macro, the lines of code that immediately follow the condition are passed on to the compiler. You must use the #endif directive to end the conditional compilation directive.

Does Ifndef need endif? ›

The #ifndef directive must be closed by an #endif directive.

What does Ifndef mean C++? ›

The #ifndef directive checks whether a macro is not defined. If the identifier specified is not defined as a macro, the lines of code immediately follow the condition are passed on to the compiler.

Is Ifdef a preprocessor AC? ›

Ifdef (The C Preprocessor)

Is Elif better than if? ›

Difference between if and if elif else

Python will evaluate all three if statements to determine if they are true. Once a condition in the if elif else statement is true, Python stop evaluating the other conditions. Because of this, if elif else is faster than three if statements.

Should I use Elif? ›

The elif statement allows you to check multiple expressions for TRUE and execute a block of code as soon as one of the conditions evaluates to TRUE. Similar to the else, the elif statement is optional.

How many else ifs can I use? ›

You can have as many else if statements as necessary. In the case of many else if statements, the switch statement might be preferred for readability. As an example of multiple else if statements, we can create a grading app that will output a letter grade based on a score out of 100.

How do you ensure a function is only called once? ›

Ensures a function is called only once. Utilizing a closure, use a flag, called , and set it to true once the function is called for the first time, preventing it from being called again.

Where should I put pragma once? ›

Using #pragma once will delegate the task, of detecting subsequent #include statements for the same file, to the compiler. It can do this efficiently and safely. As a user, there is no room for mistakes. Just place the directive in the first line of every header file.

What does pragma once do in C++? ›

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.

What is pragma in C++? ›

A pragma is a compiler directive that allows you to provide additional information to the compiler. This information can change compilation details that are not otherwise under your control. For example, the pack pragma affects the layout of data within a structure. Compiler pragmas are also called directives.

Videos

1. C++ Pragma Once
(Kevin Wood)
2. C++ #pragma once
(Kevin Wood)
3. Embedding Lua in C++ #1
(javidx9)
4. Modern C++ PRECOMPILED HEADERS - Easy and In-depth explanation with clear examples!
(Suraj Sharma)
5. Using Header Files #6 C++ Programming Fundamentals
(Virtus Learning Hub)
6. LSL Preprocessor
(ModularSystems)
Top Articles
Latest Posts
Article information

Author: Roderick King

Last Updated: 02/17/2023

Views: 6387

Rating: 4 / 5 (51 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Roderick King

Birthday: 1997-10-09

Address: 3782 Madge Knoll, East Dudley, MA 63913

Phone: +2521695290067

Job: Customer Sales Coordinator

Hobby: Gunsmithing, Embroidery, Parkour, Kitesurfing, Rock climbing, Sand art, Beekeeping

Introduction: My name is Roderick King, I am a cute, splendid, excited, perfect, gentle, funny, vivacious person who loves writing and wants to share my knowledge and understanding with you.