Традиционно стандартным и переносимым способом избежать включения нескольких заголовков в C ++ было использование #ifndef - #define - #endif
схемы директив предварительного компилятора, также называемой схемой защиты от макросов (см. Фрагмент кода ниже).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
Однако в большинстве реализаций / компиляторов (см. Рисунок ниже) существует более «элегантная» альтернатива, которая служит той же цели, что и вызванная схема защиты от макросов #pragma once
. #pragma once
имеет несколько преимуществ по сравнению со схемой защиты от макросов, в том числе меньший объем кода, предотвращение конфликтов имен и иногда повышенная скорость компиляции.
Проведя небольшое исследование, я понял, что хотя #pragma once
директива поддерживается почти всеми известными компиляторами, есть неясность в отношении того, #pragma once
является ли директива частью стандарта C ++ 11 или нет.
Вопросы:
- Может ли кто-нибудь уточнить,
#pragma once
является ли директива частью стандарта С ++ 11 или нет? - Если он не является частью стандарта C ++ 11, есть ли планы по его включению в более поздние версии (например, C ++ 14 или новее)?
- Также было бы неплохо, если бы кто-то мог более подробно рассказать о преимуществах / недостатках использования любого из методов (например, макрозащиты по сравнению с
#pragma once
).
#pragma once
обычно нет.Ответы:
#pragma once
это не стандарт. Это распространенное (но не универсальное) расширение, которое можно использоватьОн рассматривался для стандартизации, но отклонен, поскольку не может быть надежно реализован. (Проблемы возникают, когда у вас есть файлы, доступные через несколько разных удаленных подключений.)
Довольно легко убедиться, что в одной разработке нет конфликтов защиты включения. Для библиотек, которые могут использоваться многими различными разработками, очевидным решением является создание множества случайных символов для защиты включения при ее создании. (Можно настроить хороший редактор, который будет делать это за вас всякий раз, когда вы открываете новый заголовок.) Но даже без этого я еще не сталкивался с какими-либо проблемами, связанными с конфликтами между библиотеками.
источник
pragma once
нельзя переносимо реализовать что-то, что по своей сути непереносимо (и не следует даже рассматривать), - это еще одна чушь перевернутого мира C ++.#include
это необходимо удалить, потому что директиву можно слепо неправильно использовать.#pragma once
никоим образом не ограничивает переносимость, при условии, что вы не будете использовать символические ссылки для нарушения компиляции.Раздел §16.6 Стандарта ( проект N3936 ) описывает
#pragma
директивы как:В основном
#pragma once
это конкретный экземпляр#pragma
директивы для реализации, и нет, это не стандарт. Пока что.Он часто широко поддерживается большинством «основных компиляторов», включая GCC и Clang, и поэтому иногда рекомендуется избегать использования шаблона include-guard.
источник
#pragma
и#define
header-guard.#define
header-guard, у него тоже нет причин писать#pragma once
.#pragma once
d, и в случае, если он#include
снова d, может пропустить#include
(даже не открывать файл). gcc делает то же самое с защитой заголовков, но он очень и очень хрупкий.#pragma
Один легко сделать, заголовок охранник один трудно.