Нужна ли избыточная защита?

Нужны ли "избыточные защитные элементы" в Codegear RAD Studio 2009? Компилятор достаточно умен, чтобы справиться с этим самостоятельно?

Например, у меня может быть следующее 'include guard' в foo.h:

#ifndef fooH
#define fooH
// ... declaration here
#endif

и следующее "избыточное включение защиты" в use_foo.h:

#ifndef fooH
    #include "foo.h"
#endif

Кроме того, если компилятор не достаточно умен, необходимо "лишнее включать охранников", если они включены в исходный файл. например use_foo.cpp,?

3 ответа

Решение

Часть кода, которую вы пометили как "избыточное включение защиты", необязательна, но возможна оптимизация.

В случае C++Builder есть логика для обнаружения защитных заголовков, поэтому в этом нет необходимости.

В общем случае, этап предварительной обработки, как правило, довольно быстрый, поэтому вряд ли эта оптимизация так или иначе выиграет.

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

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

"Избыточная защита включения", как вы ее называете, ускоряет компиляцию.

Без избыточной защиты компилятор будет перебирать весь файл 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

(Конец редактирования)

Другие вопросы по тегам