#pragma однажды против включения охраны? - PullRequest
325 голосов
/ 17 июля 2009

Я работаю над базой кода, которая, как известно, работает только на окнах и компилируется в Visual Studio (она тесно интегрируется с Excel, поэтому никуда не денется). Мне интересно, стоит ли мне идти с традиционными включенными охранниками или использовать #pragma once для нашего кода. Я думаю, что разрешение компилятору работать с #pragma once приведет к более быстрой компиляции и будет менее подвержено ошибкам при копировании и вставке. Это также немного менее уродливо ;)

Примечание: для ускорения компиляции мы могли бы использовать Redundant Include Guards , но это добавляет тесную связь между включенным файлом и включаемым файлом. Обычно это нормально, потому что защита должна основываться на имени файла и будет меняться только в том случае, если вам все равно потребуется изменить имя включения.

Ответы [ 13 ]

4 голосов
/ 17 июля 2009

#pragma once позволяет компилятору полностью пропустить файл при его повторении - вместо того, чтобы анализировать файл, пока он не достигнет защиты #include.

Таким образом, семантика немного отличается, но они идентичны, если они используются так, как они предназначены.

Объединение обоих, вероятно, самый безопасный путь, так как в худшем случае (компилятор помечает неизвестные прагмы как фактические ошибки, а не просто предупреждения), вам просто нужно удалить сами # прагмы.

Когда вы ограничиваете свои платформы, скажем, "обычными компиляторами на рабочем столе", вы можете смело опускать защиту #include, но я тоже чувствую себя неловко по этому поводу.

OT: если у вас есть другие советы / опыт, которыми можно поделиться по ускорению сборок, мне было бы любопытно.

1 голос
/ 21 сентября 2015

поверх объяснения Конрад Кляйн выше.

Краткое резюме:

  • когда мы используем # pragma once, большая часть ответственности компилятора - не допускать его включения более одного раза. Это означает, что после того, как вы упомянули фрагмент кода в файле, это больше не ваша ответственность.

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

  • Теперь, когда мы используем #ifndef XYZ_H для заголовков, разработчик несет большую ответственность за поддержание зависимости заголовков. Это означает, что всякий раз, когда из-за какого-то нового заголовочного файла существует вероятность циклической зависимости, компилятор просто помечает некоторые сообщения об ошибках "undefined .." во время компиляции, и пользователь может проверить логическое соединение / поток объектов и исправить неправильное включает.

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

Поэтому, чтобы избежать подобных ситуаций, мы должны использовать, как;

#pragma once
#ifndef XYZ_H
#define XYZ_H
...
#endif

т.е. комбинация обоих.

1 голос
/ 18 января 2013

Для тех, кто хотел бы использовать #pragma один раз и включить охрану вместе: если вы не используете MSVC, то вы не получите много оптимизации от #pragma один раз.

И вы не должны помещать «#pragma Once» в заголовок, который должен быть включен несколько раз, причем каждое включение может иметь различный эффект.

Здесь - подробное обсуждение с примерами использования #pragma после использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...