1

The old "C" way to ensure a header file is only included once is the old idiom

#ifndef HEADER_XYZZY
#define HEADER_XYZZY

// bunch-o-common-header-stuff

#endif

But even the latest documentation on #pragma once (https://learn.microsoft.com/en-us/cpp/preprocessor/once) tells you this is better than the "old" preprocessor way for all the right reasons (does not pollute global namespace, won't actually open the file, etc.).

So, should I tweak all my precompiled header files and remove the old guards and replace it with the "modern" way? The "move on to the new century" of modern C++ tells me YES.

(I do know that the 1980's #directive guard is portable - but I'm already exclusively using Visual Studio, so #pragma is ok).

franji1
  • 3,088
  • 2
  • 23
  • 43
  • I doubt it would make any difference at all. – Retired Ninja Jan 25 '23 at 20:15
  • `#pragma once` is not standard C++. – Jesper Juhl Jan 25 '23 at 20:24
  • 1
    Precompiled header files are yours. The don't belong to Visual Studio. You can do whatever you want. That out of the way: What's the question here? – IInspectable Jan 25 '23 at 20:26
  • But it is supported by the main three compilers: gcc, clang, and msvc. I believe there are tiny differences in behavior, but those are very specific edge cases. Or so I've been told, details are fuzzy. – sweenish Jan 25 '23 at 20:27
  • 1
    `#pragma once` is not standard C++. For the compilers that support `#pragma once`, the behavior **differs** between compilers. If your project only needs to support one compiler, you can pretty much trust it's behavior will be consistent. The developer who created `#pragma once` says it has [unfixable bugs](https://stackoverflow.com/a/34884735/4641116) and not to use it. – Eljay Jan 25 '23 at 20:56
  • While *"won't actually open the file"* is true, it is not unique for the pragma. A compiler than can support this, can surely also recognize that a file had an include guard the first time it is read, and not bother to read it again. – BoP Jan 25 '23 at 21:09
  • @IInspectable to either utilize the generated 1982 guards for the pch files, OR tweak them to use the preferred `#pragma once` (asrecommended by documentation itself on `#pragma once` instead of 1982 `#ifndef/#define` include guards). So far, I want to tweak them since they ALL use THE IDENTICAL "PCH_H" as the #define across ALL my VS projects (27 of them?). The old code used a GUID-looking #define to ensure uniqueness in the global namespace. Nothing like Microsoft to redefine common verb method `Do` to `DoA` and `DoW` which then corrupts the naming of MY `Do` verbs. Yes, I'm anti-#define – franji1 Jan 25 '23 at 21:12
  • 1
    As described in the document: `can reduce build times`. It has little effect on running the program. You can use either way unless the other one doesn't work. – Minxin Yu - MSFT Jan 27 '23 at 06:35

1 Answers1

1

Unless you can guarantee your code does not need to be compiled and run using a toolchain that doesn't provide support for it, you should not use #pragma once. If you do have control of the tools that will be used and can verify support, I would suggest going ahead. It is certainly cleaner.

I'd not waste the time retrofitting old code, however.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
Mikel F
  • 3,567
  • 1
  • 21
  • 33
  • `#pragma once` is not exclusive to Windows. – sweenish Jan 25 '23 at 20:28
  • @sweenish He did specify Visual Studio, and it is not part of the language standard, and it is generally safer to stick with the standard when doing cross-platform code. – Mikel F Jan 25 '23 at 20:29
  • 1
    But it's not exclusive to Windows. *Generally*, what you're saying is true. But it makes no difference in this situation. `#pragma once` is cross-platform. Your answer paints a different, inaccurate picture. – sweenish Jan 25 '23 at 20:31
  • Do people still pollute the global namespace with the silly `#ifndef` come-up-with-some-name then immediately `#define` it for their header guards? Even worse, then put those guards around the source cpp `#include`s? That is so 1982. `#pragma once` is much preferred, even if is non-portable to some extent. In this situation, I do not need to port my MFC source code to other tools. – franji1 Jan 25 '23 at 21:01
  • @franji1 People are still locked into toolchains that do not provide the `#pragma once` option. Particularly older compiler versions to support older operating system versions. – Mikel F Jan 25 '23 at 21:06
  • Can you name a single compiler that doesn't support `#pragma once`? No googling. Did you ever use a compiler old enough to not support it? In general I'd agree that using standard features is better, but `#pragma once` is ubiquitous. – HolyBlackCat Jan 28 '23 at 17:59
  • @HolyBlackCat Yeah, I've used a compiler too old to support it. Have I been stuck using toolchains that did not support it? Yeah, I have. Are there still toolchains that may not support it? I haven't done a survey of every microcontroller compiler and such to make sure I can use it anywhere I might need it. – Mikel F Jan 29 '23 at 20:17
  • Huh! Sorry for being snarky then. – HolyBlackCat Jan 30 '23 at 03:32
  • @HolyBlackCat No worries. I think I just recently threw away my manuals for Turbo C++ 1.0. :) – Mikel F Jan 30 '23 at 17:04