Нужна ли избыточная защита? - PullRequest
4 голосов
/ 10 февраля 2010

Нужны ли «избыточные защитные устройства» в 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 ]

5 голосов
/ 10 февраля 2010

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

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

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

3 голосов
/ 10 февраля 2010

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

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

2 голосов
/ 10 февраля 2010

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

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

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

...