Нужно некоторое разъяснение по #pragma Once

Я искал повсюду некоторые разъяснения о том, что на самом деле делает #pragma Once, и не могу найти окончательных ответов на некоторые вопросы, которые у меня все еще есть.

Гарантирует ли #pragma once, что заголовочный файл, в который он включен, вызывается только один раз, ТАК ЖЕ, что заголовки, включенные в указанный заголовочный файл, еще не включены? Кроме того, если он вызывается только один раз, означает ли это, что файл .cpp, которому нужен определенный заголовок, не сможет получить к нему доступ? Если файл заголовка помечен #pragma один раз и включен в .cpp, можно ли снова использовать этот файл заголовка в другом месте?

Таких разъяснений я не нахожу. Извините, если где-то есть документация, которая разъясняет это, но я действительно не смог найти ничего достаточно конкретного.


person NanoTree    schedule 18.02.2014    source источник
comment
Обратите внимание, что, хотя он обычно поддерживается, технически он не является стандартным.   -  person chris    schedule 18.02.2014


Ответы (3)


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

Вы все еще можете включить его снова из другого .cpp.

Файл обычно идентифицируется по номеру индекса.

Обратите внимание, что #pragma once строго нестандартен, и большинство по-прежнему предпочитает традиционные средства защиты заголовков #ifndef.

person Potatoswatter    schedule 18.02.2014
comment
Это немного помогает мне, и, поскольку я играю с DirectX, в первую очередь код не является платформой для мобильных устройств. Я предполагаю, что мне нужно понять сейчас, что такое единица перевода, которая, я уверен, хорошо документирована, а также специфична для компилятора? - person NanoTree; 18.02.2014
comment
@ManicCure, проще говоря, это один (cpp) файл и все заголовки, прямо или косвенно включенные в него. Если вам нужно стандартное определение, текст программы хранится в единицах, называемых исходными файлами в этом международном стандарте. Исходный файл вместе со всеми заголовками (17.6.1.2) и исходными файлами, включенными (16.2) с помощью директивы предварительной обработки #include, за вычетом всех исходных строк, пропущенных любой из директив условного включения (16.1) предварительной обработки, называется единицей трансляции. - person chris; 18.02.2014
comment
standard => supported --> en.wikipedia.org/wiki/Pragma_once - person Andreas detests censorship; 15.01.2019
comment
@Andreas широко поддерживается! = хорошая практика. Здесь много споров, которые не стоит повторять. - person Potatoswatter; 15.01.2019

#pragma once заставляет текущий исходный файл включаться только один раз в одну компиляцию. По сути, это похоже на #include охранников.

person shivakumar    schedule 18.02.2014
comment
хорошо, так что, вы можете помочь мне понять, что такое компиляция? потому что для меня это звучит так, что компилятор будет игнорировать все включения одного и того же заголовочного файла, даже если это может быть необходимо, и в противном случае не вызовет ошибку компилятора, что приведет к ошибке компилятора. Смущенный? Я знаю, что я... #include охранники имеют очень очевидную логику; #pragma Once не делает этого, потому что действия, предпринимаемые компилятором, не сообщаются читателю кода. - person NanoTree; 18.02.2014

Гарантирует ли #pragma once, что заголовочный файл, в который он включен, вызывается только один раз, ТАК ЖЕ, что заголовки, включенные в указанный заголовочный файл, еще не включены?

Прагма не влияет на другие заголовки. если заголовок с прагмой «a.h» включает «b.h», «b.h» может быть снова включен через третий заголовок или напрямую.

Кроме того, если он вызывается только один раз, означает ли это, что файл .cpp, которому нужен определенный заголовок, не сможет получить к нему доступ?

Вы можете включить заголовок из любого места столько раз, сколько считаете нужным.

Если файл заголовка помечен #pragma один раз и включен в файл .cpp, можно ли снова использовать этот файл заголовка в другом месте?

Да, это нормальная практика с заголовками.


Где подвох?

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

Преимущество pragma once заключается в том, что он избавляет вас от ошибок, таких как наличие 2 файлов заголовков, которые случайно имеют один и тот же макрос часового. это может произойти, когда 2 файла заголовков имеют одинаковое имя файла и один и тот же стиль кодирования для имен макросов.

person egur    schedule 18.02.2014
comment
С тех пор #pragma Once может быть включен в каждый создаваемый вами заголовочный файл, и у вас никогда не возникнет проблем с необъявленным идентификатором, если вы включили все нужные файлы? - person NanoTree; 18.02.2014
comment
@ManicCure pragma once предотвращает только дублирование объявлений. Включение всех нужных файлов — сложная часть. Проблема в том, что C++ может работать медленно, если вы включаете слишком много ложных зависимостей. - person Potatoswatter; 18.02.2014
comment
Вот так. Если вам нужна более высокая скорость компиляции, прочитайте о предварительно скомпилированных заголовках. Но это другой вопрос. - person egur; 18.02.2014