Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the dangers of using #pragma once? [duplicate]

Tags:

c++

c

macros

Modern C and C++ compilers support the non-standard #pragma once, preprocessor directive, which serve a similar purpose to the classic header guards:

#ifndef hopefully_unique_identifier_that_doesnt_hurt_the_code
#define hopefully_unique_identifier_that_doesnt_hurt_the_code
  // some code here
#endif

One problem, I'm aware of, with the classic approach is that once you've included a header, you have to #undef the header guard macro to include it again (doing so, to me, is a major code-smell, but that's beside the point here). The same problem arises with the #pragma once approach, but without the possibility of allowing the header to be included more than once.

Another problem with the classic-approach is that you may, accidentally, define the same macro in unrelated places, thus either not including the header as expected or doing some other nasty stuff, that I can't imagine. This is reasonably easy to avoid in practice, by keeping to certain conventions such as basing the macros to UUID-like objects (i.e. random strings) or (the less optimal approach), basing them on the name of the file, they are defined in.

I have only rarely experienced any of these, potential problems, in real life, so I don't really consider them to be major problems.

The only potential real life problem I can think of with #pragma once, is that it's not a standard thing -- you're relying on something that may not be available everywhere, even if it is present, in practice, everywhere (*).

So, what potential problems exist with #pragma once, besides the ones I've already mentioned? Am I having too much faith in having it available, in practice, everywhere?

(*) Some minor compiler that only a handful of people use, excluded.

like image 975
Clearer Avatar asked Dec 15 '17 10:12

Clearer


People also ask

What are the dangers of substance use?

Risks of Substance UseAffect the growth and development of teens, especially brain development. Occur more frequently with other risky behaviors, such as unprotected sex and dangerous driving. Contribute to the development of adult health problems, such as heart disease, high blood pressure, and sleep disorders.

What a drug does to the body?

Drugs affect your body's central nervous system. They affect how you think, feel and behave. The three main types are depressants, hallucinogens and stimulants: Depressants slow or 'depress' the function of the central nervous system. They slow the messages going to and from your brain.


3 Answers

One problem I have encountered with using #pragma once was when including the same file that is located at multiple locations. With #pragma once it is deemed different, not with #ifndef/#define guard.

like image 195
piwi Avatar answered Oct 24 '22 10:10

piwi


In using #pragma once you are giving up portability. You are no longer writing C or C++, but something allowed as a compiler extension.

That could cause you headaches if your code ever targets a different platform.

It's for this reason that I never use it.

Given that the name and location of a file is unique, I use that as my include guard. Furthermore because I have in the past targetted very old preprocessors, I use as a habit

#if !defined(foo)
#define foo 1
/*code*/
#endif

which has worked on every platform I've encountered since 1996.

like image 45
Bathsheba Avatar answered Oct 24 '22 11:10

Bathsheba


I have worked with a decent set of compilers so far:

  • GCC
  • Clang/LLVM
  • IBM XLC
  • Intel C++ Compiler

The only compiler that does not support #pragma once is the IBM XLC compiler, that that one does not even support C++11, so I am not interested. If you need to work with the IBM XLC Compiler on Blue Gene/Q, then you cannot use #pragma once.

A long time ago, certain compilers did not understand the include guard idiom and would repeatedly open the header file only to find that the preprocessor reduced the content to nothing. With these compilers, using #pragma once would give compile time benefit. However, this has been implemented in major compilers, such that this makes no difference nowadays.

Perhaps you have some special compiler for your embedded system. That one might be unable to use #pragma once.

In general I prefer #pragma once because when you duplicate a header file in order to do incremental refactoring by duplication or extending a class, you cannot forget to change the name of the include guard macro.

Therefore I do not know of any hard problem you have with #pragma once, except for certain compilers.

like image 39
Martin Ueding Avatar answered Oct 24 '22 10:10

Martin Ueding