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

时间:2023-01-21 15:04:51

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 - #endifpre-compiler directive scheme也称为macroguard scheme(参见下面的代码片段)。

#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 once has several advantages compared to the macro-guard scheme, including less code, avoidance of name *es, and sometimes improved compile speed.

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

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

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

做了一些研究之后,我意识到尽管#pragma曾经的指令被几乎所有已知的编译器所支持,但是对于#pragma曾经的指令是否属于c++ 11标准的一部分,还是存在着一个模糊的问题。

Questions:

  • Could someone clarify whether #pragma once directive is part of the C++11 standard or not?
  • 有人能澄清#pragma曾经的指令是否是c++ 11标准的一部分吗?
  • 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)?
  • 如果它不是c++ 11标准的一部分,是否有计划在以后的版本中包含它(例如,c++ 14或更高版本)?
  • 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一次)。

2 个解决方案

#1


86  

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

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

  • 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.

很容易确保在单个开发中不存在包含保护冲突。对于可能被许多不同的开发所使用的库,显而易见的解决方案是在创建时生成大量的随机字符。(只要打开一个新的页眉,就可以为您设置一个好的编辑器。)但是,即使没有这些,我还没有遇到库之间冲突的任何问题。

#2


26  

Section §16.6 of the Standard (N3936 draft) describes #pragma directives as:

部分§16.6的标准(N3936草案)描述# 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都将被忽略。

Basically #pragma once is an implementation specific instance of a #pragma directive, and no, it's not standard. Yet.

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

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

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

#1


86  

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

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

  • 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.

很容易确保在单个开发中不存在包含保护冲突。对于可能被许多不同的开发所使用的库,显而易见的解决方案是在创建时生成大量的随机字符。(只要打开一个新的页眉,就可以为您设置一个好的编辑器。)但是,即使没有这些,我还没有遇到库之间冲突的任何问题。

#2


26  

Section §16.6 of the Standard (N3936 draft) describes #pragma directives as:

部分§16.6的标准(N3936草案)描述# 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都将被忽略。

Basically #pragma once is an implementation specific instance of a #pragma directive, and no, it's not standard. Yet.

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

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

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