Для чего нужна команда pragma once?
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Здравствуйте. Очень часто встречаю конструкцию
#pragma once
в чужих исходниках. Скажите, для чего она нужна?Илья, директива препроцессора
#pragma once
применяется для защиты от «двойного подключения» заголовочных файлов.Например, у нас есть 3 файла —
main.cpp
,header.h
иsomething.cpp
.header.h
something.cpp
main.cpp
Файл
header.h
подключается одновременно вmain.cpp
иsomething.cpp
. Из за этого объявление классаFoo
будет выполнено более одного раза, и мы получим ошибку при компиляции.Для того, чтобы избежать подобных проблем, используется директива
#pragma once
, которая указывает препроцессору, что файл подключается только один раз.Еще один вариант — include guard, который в отличии от
#pragma once
, умеет корректно работать с символическими ссылками.Большое спасибо! Буду разбираться.
5 за старание
На счёт
#pragma once
— всё правильно. Более того, Микрософт пишет, что эта прагма сокращает время компиляции, поскольку файлы обрабатываются только один раз. Сильно подозреваю, что в этом случае для компиляции требуется больше оперативной памяти — бесплатный сыр, как известно...А вот твой пример не совсем корректный.
В данном случае будет профит только от сокращения времени компиляции. Двойного определения класса
Foo
здесь не будет в любом случае.Файлы main.cpp и something.cpp являются отдельными единицами компиляции и встретятся только на этапе сборки, поэтому header.h будет включаться в них независимо друг от друга.
Для двойного включения нужна немного другая конструкция:
header1.h
main1.cpp
Вот в этом случае заголовочный файл
<iostream>
должен быть защищён от двойного включения, поскольку при обработке файла main1.cpp сначала он включается явно директивой#include
, а затем неявно при включении заголовочного файла header1.h.Причём файл something1.cpp, содержащий реализацию функции
bar()
, мы здесь не рассматриваем, поскольку это опять-таки отдельная единица компиляции.Замечание для начинающих. При компиляции каждый файл .cpp сначала обрабатывается препроцессором. Препроцессор — штука по своей логике достаточно примитивная: читает текст программы из входного файла, обрабатывает директивы препроцессора (
#include
,#define
,#if/#elif/#else/#endif
и пр., но не#pragma
(!) — это не директива препроцессора) и макросы и пишет получившийся текст программы во временный файл, откуда его потом подхватывает компилятор. Найдя директиву#include
, препроцессор тупо заменяет её на содержимое указанного в директиве файла и продолжает обрабатывать получившийся текст.Да, точно. Спасибо :)