Home c++ # ifndef / # define VS #pragma once

# ifndef / # define VS #pragma once [duplicate]

Author

Date

Category

Please tell me what is the difference between the two directives and which one is better to use in the code?

MyClass.h file

# include & lt; iostream & gt;
#include & lt; string & gt;
#ifndef MYCLASS_H
#define MYCLASS_H
// class description
#endif

Or

# pragma once
#include & lt; iostream & gt;
#include & lt; string & gt;
// class description

Answer 1, authority 100%

The #pragma once directive is compiler implementation dependent, and therefore may not be supported by individual compilers and will simply be ignored.

The directives #ifndef and #define are standard directives, and therefore their use in this context will be the same for all compilers.


Answer 2, authority 96%

The fundamental difference is that #pragma once refers to the entire header file. The original idea of ​​#pragma once was that in the process of processing a single translation unit, the compiler (preprocessor) has the right to not even search for or open a second time header files that contain #pragma once . It was in this form that it was once proposed to standardize #pragma once as a means of speeding up compilation.

Include guards # ifdef / # endif , of course, do not have the right to cover the entire header file, i.e. this pair does not generally apply to the entire file. This means that, in general, the compiler will have to find and open the header file to include sections that are not inside # ifdef / # endif .

At the same time, it is clear that the compiler does not have any difficulty in analyzing the contents of the header file on first reading and recognizing the explicit idiomatic use of # ifdef / # endif , which scrolls the entire file from beginning to end. In such a situation, #pragma once provides no practical benefit over # ifdef / # endif . It is for this reason that the standardization of #pragma once was abandoned at one time – as a feature that does not bring any additional value (except, perhaps, a compact recording and the fact that, as @vp_arth and @VladD , no need to invent a unique identifier).

Accordingly, the answer is obvious – use the standard functionality # ifdef / # endif and forget about the non-standard #pragma once . Maybe in some case you will notice that the compiler (preprocessor) does not want to optimize processing based on the analysis of # ifdef / # endif and using #pragma once really speeds up compilation. .. Then, if this is critical for you, it may be worth adding #pragma once to your files.

Another consideration against the standardization of #pragma once was that in order to provide a strict guarantee of its specification (that is, strictly a single inclusion), it is necessary to be able to reliably determine the identity of the file as specified in the directive #include paths. This task is generally extremely difficult to solve in many existing file systems. So beware of naive pioneering statements like “all modern compilers support #pragma once “. There is no question of any compiler support for a strict specification. And, of course, there is no question of any guarantees of the same behavior between compilers. For this reason, if you are going to use #pragma once in your code, use it together with include guards, not instead of them.

P.S. Including other header files is usually “put” inside your # ifdef / # endif . There is no reason for them to be outside. By leaving them outside, you may run the risk of overwhelming the aforementioned optimization. If you already use # ifdef / # endif , then in the vast majority of cases they should cover the entire file from beginning to end.


Answer 3, authority 98%

Portability

Many compilers that do not support #pragma once today tend to empty. Basically, there are now undeveloped or abandoned.

The enWiki has a table with links to sources. In this list, only PGI does not support #pragma once . < br>
Listed on ruWiki OracleSolarisStudio fixed this omission in version 12.5

Speed ​​up compilation

This plus is very illusive. You may not achieve acceleration of compilation from using it, compilers are able (gcc for sure) to optimize both.

Collisions

The main disadvantage of include guards is that you cannot guarantee that you have come up with a unique identifier.

If you never plan to include foreign libraries, you can come up with a rule for include guards and live in peace.
Otherwise, they break everything that C++ namespaces exist for. Simple MYCLASS_H is clearly not enough, because it may already be defined in another plug-in library, or, if you are writing a library, in the client code.
You have to come up with really unique identifiers, like __VENDOR_PACKAGE_MYCLASS or __MYCLASS_% TIMESTAMP% , to avoid collisions.

Resume

Of course, what exactly to use in your project is up to you. However, there is obviously no reason not to use a more concise version other than the fanatical “Not in the standard “.


PS: You are using include guards incorrectly – they must cover the entire file as a whole, otherwise the compiler will not be able to optimize them in any way so as not to run the preprocessor for this file again.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions