#pragma 曾经是 C++11 标准的一部分吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23696115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:31:42  来源:igfitidea点击:

Is #pragma once part of the C++11 standard?

c++c++11macrosheader-filesc++14

提问by 101010

Traditionally, the standard and portable way to avoid multiple header inclusions in C++ was/is to use the #ifndef - #define - #endifpre-compiler directives scheme also called macro-guard scheme(see code snippet below).

传统上,避免在 C++ 中包含多个头文件的标准和可移植方法是/是使用#ifndef - #define - #endif预编译器指令方案,也称为宏保护方案(参见下面的代码片段)。

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

In most implementations/compilers (see picture below) however, there's a more "elegant" alternative that serves the same purpose as the macro-guard scheme called #pragma once. #pragma oncehas several advantages compared to the macro-guard scheme, including less code, avoidance of name clashes, and sometimes improved compile speed.

然而,在大多数实现/编译器(见下图)中,有一个更“优雅”的替代方案,与称为#pragma once. #pragma once与宏保护方案相比,它有几个优点,包括更少的代码、避免名称冲突,有时还提高了编译速度。

enter image description here

在此处输入图片说明

Doing some research, I realized that although #pragma oncedirective is supported by almost all known compilers, there's a turbidness on whether #pragma oncedirective is part of the C++11 standard or not.

做了一些研究,我意识到尽管#pragma once几乎所有已知的编译器都支持指令,但指令是否#pragma once是 C++11 标准的一部分还不清楚。

Questions:

问题:

  • Could someone clarify whether #pragma oncedirective is part of the C++11 standard or not?
  • If it's not part of the C++11 standard, are there any plans on including it on later releases (e.g., C++14 or later)?
  • It would also be nice if someone could further elaborate on the advantages/disadvantages in using either one of the techniques (i.e., macro-guard versus #pragma once).
  • 有人可以澄清#pragma once指令是否是 C++11 标准的一部分吗?
  • 如果它不是 C++11 标准的一部分,是否有计划将其包含在更高版本(例如,C++14 或更高版本)中?
  • 如果有人可以进一步详细说明使用其中一种技术(即宏保护与#pragma once)的优缺点,那也很好。

采纳答案by James Kanze

#pragma onceis notstandard. It is a widespread (but not universal) extension, which can be used

#pragma once不是标准。它是一个广泛的(但不是普遍的)扩展,可以使用

  • if your portability concerns are limited, and
  • you can be sure that all of your include files are always on a local disk.
  • 如果您的便携性问题有限,并且
  • 您可以确保所有包含文件始终位于本地磁盘上。

It was considered for standardization, but rejected because it cannot be implemented reliably. (The problems occur when you have files accessible through several different remote mounts.)

曾考虑将其标准化,但因无法可靠实施而被拒绝。(当您可以通过多个不同的远程安装访问文件时,就会出现问题。)

It's fairly easy to ensure that there are no include guard conflicts within a single development. For libraries, which may be used by many different developments, the obvious solution is to generate a lot of random characters for the include guard when you create it. (A good editor can be set up to do this for you whenever you open a new header.) But even without this, I've yet to encounter any problems with conflicts between libraries.

确保在单个开发中不存在包含保护冲突是相当容易的。对于可能被许多不同开发使用的库,显而易见的解决方案是在创建包含守卫时为它生成大量随机字符。(每当你打开一个新的标题时,一个好的编辑器可以为你做这件事。)但即使没有这个,我还没有遇到任何库之间冲突的问题。

回答by Shoe

Section §16.6 of the Standard (N3936draft) describes #pragmadirectives as:

标准(N3936草案)的第 16.6 节将#pragma指令描述为:

A preprocessing directive of the form

# pragma pp-tokensopt new-line

causes the implementation to behave in an implementation-defined manner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any pragma that is not recognized by the implementation is ignored.

形式的预处理指令

# pragma pp-tokensopt new-line

导致实现以实现定义的方式运行。该行为可能会导致翻译失败或导致翻译器或生成的程序以不符合规定的方式运行。任何未被实现识别的编译指示都会被忽略。

Basically #pragma onceis an implementation specific instance of a #pragmadirective, and no, it's not standard. Yet.

基本上#pragma once#pragma指令的实现特定实例,不,它不是标准的。然而。

It is often widely supported by most "major compilers" including GCCand Clangand is therefore sometimes recommended to avoid include-guards boilerplate.

它通常被大多数“主要编译器”(包括GCCClang)广泛支持,因此有时建议避免包含保护样板。