Является ли #pragma когда-то частью стандарта С++ 11?

Традиционно стандартный и переносимый способ избежать включения нескольких заголовков в С++ заключался в использовании схемы директив #ifndef - #define - #endif pre-compiler, также называемой схемой макро-защиты (см. фрагмент кода ниже).

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

Однако в большинстве реализаций/компиляторов (см. рисунок ниже) существует более "изящная" альтернатива, которая служит той же цели, что и схема макро-защиты #pragma once. #pragma once имеет несколько преимуществ по сравнению с макроблочной схемой, включая меньше кода, избегание конфликтов имен, а иногда и улучшенную скорость компиляции.

enter image description here

Проведя некоторые исследования, я понял, что хотя директива #pragma once поддерживается почти всеми известными компиляторами, существует мутность в отношении того, является ли директива #pragma once частью стандарта С++ 11 или нет.

Вопросы:

  • Может ли кто-нибудь уточнить, является ли директива #pragma once частью стандарта С++ 11 или нет?
  • Если он не является частью стандарта С++ 11, существуют ли какие-либо планы по включению его в более поздние версии (например, С++ 14 или новее)?
  • Было бы неплохо, если бы кто-то еще мог подробнее разобраться в преимуществах/недостатках использования одного из методов (т.е. макро-защиты против #pragma once).

Ответ 1

#pragma once не является стандартным. Это широко распространенный (но не универсальное) расширение, которое можно использовать

  • Если ваши проблемы с переносимостью ограничены, и
  • вы можете быть уверены, что все ваши включенные файлы всегда находятся на локальном диске.

Он рассматривался для стандартизации, но отклонялся, потому что он не могут быть надежно реализованы. (Проблемы возникают, когда вы файлы доступны через несколько разных удаленных устройств.)

Довольно легко убедиться, что нет защитника конфликтов в рамках одного развития. Для библиотек, которые могут будет использоваться многими различными разработками, очевидным решением является для генерации большого количества случайных символов для включенного охранника когда вы его создаете. (Можно создать хороший редактор, чтобы сделать это для когда вы открываете новый заголовок.) Но даже без этого, Я еще не сталкивался с проблемами с конфликтами между библиотеки.

Ответ 2

Раздел 16.6 стандарта (N3936 описывает директивы #pragma как:

Директива предварительной обработки формы

# pragma pp-tokensopt new-line

приводит к тому, что реализация ведет себя в определенном реализацией манера. Поведение может привести к ошибке перевода или вызвать переводчик или результирующая программа, чтобы вести себя в несоответствующей манера. Любая прагма, не признанная реализацией, игнорируются.

В основном #pragma once - конкретный экземпляр директивы #pragma, специфичный для реализации, и нет, он не является стандартным. Все же.

Он часто поддерживается большинством "основных компиляторов", включая GCC и Clang. и поэтому иногда рекомендуется избегать включения контрольной плитки.