Нужны ли резервные охранники?
-
19-09-2019 - |
Вопрос
Нужны ли «избыточные средства защиты включения» в Codegear RAD Studio 2009?Достаточно ли умен компилятор, чтобы справиться с этим самостоятельно?
Например, в foo.h у меня может быть следующее «включить охрану»:
#ifndef fooH
#define fooH
// ... declaration here
#endif
и следующее «избыточное включение защиты» в use_foo.h:
#ifndef fooH
#include "foo.h"
#endif
Кроме того, если компилятор недостаточно умен, необходимы ли «избыточные средства защиты включения», если они включаются в исходный файл.например use_foo.cpp
. ?
Решение
Часть кода, которую вы пометили как «избыточную защиту включения», не является обязательной, но это возможный оптимизация.
В случае C++Builder существует логика для обнаружения защиты заголовков, поэтому в этом нет необходимости.
В общем случае этап предварительной обработки в любом случае обычно выполняется довольно быстро, поэтому маловероятно, что этот оптимизация в любом случае принесет вам много пользы.
Другие советы
Эти избыточные защитные элементы предназначены для имитации функциональности предлагаемого #pragma once
директива:если какой-то заголовочный файл уже был включен, то препроцессор даже не будет больше пытаться найти, открыть и проанализировать его (как это было бы при использовании «обычного» метода защиты включения).Во многих случаях это делает обработку включаемых файлов более эффективной (ускоряет компиляцию).
Этот подход, очевидно, требует большого обслуживания:необходимо убедиться, что написание защитного символа одинаково как внутри заголовочного файла, так и снаружи.
«Избыточная защита включения», как вы это называете, ускоряет компиляцию.
Без избыточной защиты компилятор будет перебирать весь файл foo.h в поисках кода, который может находиться за пределами #ifndef
блокировать.Если это длинный файл и это делается во многих местах, компилятор может потратить много времени.Но с избыточной защитой он может пропустить весь #include
заявление и даже не открывать этот файл повторно.
Конечно, вам придется поэкспериментировать и увидеть фактическое количество времени, потраченное компилятором на итерацию foo.h и фактически ничего не компилируя;и, возможно, современные компиляторы действительно ищут этот шаблон и автоматически решают, что файл вообще не нужно открывать, я не знаю.
(Начало редактирования с 280Z28)
Следующая структура заголовка распознается по меньшей мере GCC и MSVC.Использование этого шаблона сводит на нет практически все преимущества, которые вы могли бы получить от защиты во включаемых файлах.Обратите внимание, что комментарии игнорируются, когда компилятор проверяет структуру.
// GCC will recognize this structure and not reopen the file
#ifndef SOMEHEADER_H_INCLUDED
#define SOMEHEADER_H_INCLUDED
// Visual C++ uses #pragma once to mark headers that shouldn't be reopened
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// header text goes here.
#endif
(Конец редактирования)