Только что видел это внутри
#ifndef BOOST_ASIO_HPP
#define BOOST_ASIO_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
/// ....
#endif // BOOST_ASIO_HPP
Не обращая внимания на проверки препроцессора _MSC_VER
, в чем преимущество наличия #pragma Once
в этом случае? Разве защита заголовка препроцессора не гарантирует, что во всех случаях и на всех платформах содержимое заголовка включается только только
один раз?
#pragma once
указывает, что файл будет включен (открыт) только один раз пользователем компилятор при компиляции файла с исходным кодом. Это может сократить время сборки, поскольку компилятор не будет открывать и читать файл после первого #include
модуля.
Если вы не выполните #pragma один раз
, файл будет открываться каждый раз , когда он понадобится, и компилятор прекратит его анализ на #ifndef BOOST_ASIO_HPP
, если он был определен.
#pragma once
имеет ту же цель, но включить охранники предназначены для более глубокого анализа, чтобы гарантировать, что файл включен ровно один раз - например,
// somerandomfileinmyproject.cpp
#undef BOOST_ASIO_HPP
#include <bost/asio.cpp>
Если компилятор не обрабатывает такие случаи правильно, ему все равно необходимо открыть файл и передать его через препроцессор, даже если он был включен ранее.
Да, защита заголовков гарантирует, что содержимое заголовка будет включено только один раз. но здесь вы используете #pragma для проверки другого определения, а не для включения файла.
Ссылка ниже - это существующий вопрос о защите заголовков в SO.
Вы можете воспроизвести эффект от #pragma once
стандартным способом, используя следующее:
#if !defined GUARD_SYMBOL
#include "GUARDED_FILE"
#endif
хотя он гораздо более многословен. Как говорили другие, это помогает при компиляции, поскольку файл не ищется/открывается, вместо того, чтобы открыть файл и игнорировать все, что в нем находится - файл все равно должен быть разобран препроцессором.