#ifndef/#define VS #pragma once [дубликат]

1,00
р.



На этот вопрос уже дан ответ здесь:

Защита от множественного подключения заголовочного файла
(1 ответ)
Закрыт 7 лет назад.

Подскажите пожалуйста, в чём разница между двумя директивами и какую лучше использовать в коде?
Файл MyClass.h
#include #include #ifndef MYCLASS_H #define MYCLASS_H
//class description
#endif
Или
#pragma once #include #include
//class description

Ответ
Фундаментальное отличие заключается в том, что #pragma once относится ко всему заголовочному файлу целиком. Изначальной идеей #pragma once было то, что в процессе обработки отдельной единицы трансляции компилятор (препроцессор) имеет право даже и не искать и не открывать второй раз заголовочные файлы, которые содержат #pragma once. Именно в этой форме когда-то и предлагалось стандартизовать #pragma once - как средство ускорения компиляции.
Include guards #ifdef/#endif, понятное дело, имеют право покрывать не весь заголовочный файл, т.е. эта пара в общем случае не относится ко всему файлу целиком. Это означает, что в общем случае компилятор будет вынужден найти и открыть заголовочный файл, чтобы включить участки, не попавшие внутрь #ifdef/#endif.
В то же время понятно, что компилятору не составляет никакого труда проанализировать содержимое заголовочного файла при первом прочтении и распознать явное идиоматическое использование #ifdef/#endif, прокрывающее весь файл целиком от начала до конца. В такой ситуации #pragma once не предоставляет никакой практической выгоды по сравнению с #ifdef/#endif. Именно по этой причине от стандартизации #pragma once в свое время отказались - как от фичи, не привносящей никакой дополнительной ценности (кроме, разве что, компактной записи и того, что, как заметили @vp_arth и @VladD, нет необходимости выдумывать уникальный идентификатор).
Соответственно, ответ очевиден - пользуйтесь стандартной функциональностью #ifdef/#endif и забудьте про нестандартный #pragma once. Может быть в каком-то случае вы заметите, что компилятор (препроцессор) не хочет оптимизировать обработку на основе анализа #ifdef/#endif и использование #pragma once действительно ускоряет компиляцию... Тогда, если для вас это критично - может быть стоит добавить в ваши файлы #pragma once.
Еще одно соображение против стандартизации #pragma once заключалось в том, что для обеспечения жесткой гарантии ее спецификации (т.е. строго единственного включения), необходимо иметь возможность надежно определять идентичность файла по указанному в директиве #include пути. Это задача в общем случае исключительно трудноразрешима во многих существующих файловых системах. Поэтому будьте осторожны с наивными пионерскими заявлениями типа "все современные компиляторы поддерживают #pragma once". Ни о какой поддержке строгой спецификации ни в одном компиляторе речи не идет. И, разумеется, ни о каких гарантиях одинаковости поведения между компиляторами речи не идет тоже. По этой причине, если вы таки соберетесь использовать #pragma once в своем коде, используйте ее вместе с include guards, а не вместо их.
P.S. Включение других заголовочных файлов обычно "кладут" внутрь вашего #ifdef/#endif. Им нет никакой причины находиться снаружи. Манерой оставлять их снаружи вы, возможно, рискуете подавить вышеупомянутую оптимизацию. Если уж вы пользуетесь #ifdef/#endif, то в подавляющем большинстве случаев они должны покрывать весь файл от начала до конца.