Должен ли я по-прежнему использовать #include охранники AND #pragma один раз?
![enter image description here]()
http://en.wikipedia.org/wiki/Pragma_once
Должен ли я по-прежнему использовать include guard, когда все эти компиляторы поддерживают #pragma once
?
Многие ответы на переполнение стека говорят, что они используются как для совместимости, но я не уверен, что это все еще верно.
Какие компиляторы сегодня не поддерживают #pragma once
?
Я не уверен, что использование обоих рекомендаций было только рекомендацией, прежде чем оно вступило в силу, или если есть все еще очень веские причины для использования обоих методов.
Любые примеры использования #pragma once
могут вызвать проблемы?
Ответы
Ответ 1
Это зависит от того, насколько переносится ваша программа.
Пока вы пишете программу, которая должна работать с компиляторами, которые, как вы знаете, определенно поддерживают #prama once
, достаточно использовать #pragma once
. Но при этом вы ограничиваете свою программу набором компиляторов, которые поддерживают определенную реализацию.
Если вам нужна ваша программа для работы с всеми компиляторами, тогда вы должны использовать #pragma once
и включить защитные устройства.
Если компилятор не поддерживает #pragma once
, он просто игнорирует его [Ref # 1] в этом случае защитники заголовков будут служить вам цели, поэтому ничего неправильного в их использовании так как вы не знаете о функциях, поддерживаемых вашими компиляторами.
Итак, если вы хотите, чтобы ваша программа была на 100% переносимой на разных компиляторах, идеальным способом все еще остается использовать только защитные устройства. Поскольку @CharlesBailey справедливо указывает, поскольку поведение для #pragma once
является реализацией, поведение на неизвестном компиляторе может иметь пагубное влияние на вашу программу.
[Ref # 1]
Стандартная С++ 03: 16.6 Директива Pragma
Директива предварительной обработки формы
# pragma pp-tokensopt new-line
заставляет реализацию вести себя определенным образом. Любая прагма, которая не распознается реализацией, игнорируется.
Ответ 2
Это нестандартно, поэтому, если вы хотите быть в безопасности, используйте включенные охранники
Ответ 3
Как показывает ваша таблица, очень редко встречается компилятор в обычном использовании, который не поддерживает #pragma once
. Чтобы сохранить базу кода, чистую и дешевую для обслуживания, необходимо постоянное усилие рефакторинга. Необходимость обновления включать охранники каждый раз, когда вы переименовываете класс или перемещать некоторый код вокруг, добавляет существенную нагрузку на эти усилия.
Поэтому я бы сказал, что помимо некоторых нишевых угловых дел или для сломанных систем сборки #pragma once
на практике безопасно полагаться. Если вы заботитесь о производительности и качестве кода, используя только #pragma once
, кажется очевидным выбором.
Исключения составляют, если вы пишете библиотеку, которая должна поддерживать каждый компилятор под солнцем или, к сожалению, достаточно для работы с одним из этих редких компиляторов, который не имеет этой функции.