Должен ли я по-прежнему использовать #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, кажется очевидным выбором.

Исключения составляют, если вы пишете библиотеку, которая должна поддерживать каждый компилятор под солнцем или, к сожалению, достаточно для работы с одним из этих редких компиляторов, который не имеет этой функции.