#pragma однажды по сравнению с включают защиту? [дубликат]

Один типичный пример для использования volatile должен использовать volatile boolean переменная как флаг для завершения потока. Если Вы запустили поток, и Вы хотите быть в состоянии безопасно прервать его от различного потока, у Вас может быть поток, периодически проверяют флаг. Для остановки его установите флаг на истинный. Путем создания флага volatile, можно удостовериться, что поток, который проверяет его, будет видеть, что это было установлено в следующий раз, когда это проверяет его, не имея необходимость даже использовать synchronized блок.

342
задан Jonathan Leffler 21 November 2018 в 17:07
поделиться

6 ответов

Я не думаю, что это существенно повлияет на время компиляции, но #pragma once очень хорошо поддерживается компиляторами, но фактически не является частью стандарта. Препроцессор может работать с ним немного быстрее, так как с ним проще понять ваше точное намерение.

#pragma once менее подвержена ошибкам и требует меньше кода.

Для ускорения компиляции. time more просто пересылайте объявление вместо включения в файлы .h, когда можете.

Я предпочитаю использовать #pragma один раз .

См. Эту статью в википедии о возможности использования обоих .

297
ответ дан 23 November 2019 в 00:33
поделиться

Если вы уверены, что никогда не будете использовать этот код в компиляторе, который его не поддерживает (Windows / VS, GCC и Clang - примеры компиляторов, которые поддерживают ), то вы можете без проблем использовать #pragma один раз.

Вы также можете просто использовать оба (см. Пример ниже), чтобы получить переносимость и ускорение компиляции на совместимых системах

#pragma once
#ifndef _HEADER_H_
#define _HEADER_H_

...

#endif
23
ответ дан 23 November 2019 в 00:33
поделиться

Пока #pragma once не станет стандартным (в настоящее время это не является приоритетом для будущих стандартов), я предлагаю вам использовать его И использовать охранники, это путь:

#ifndef BLAH_H
#define BLAH_H
#pragma once

// ...

#endif

Причины:

  • #pragma once не является стандартным, поэтому возможно, что какой-то компилятор не предоставляет эту функциональность. Тем не менее, его поддерживают все основные компиляторы. Если компилятор этого не знает, по крайней мере, он будет проигнорирован.
  • Поскольку стандартного поведения для #pragma once не существует, не следует предполагать, что поведение будет одинаковым для всех компиляторов. Охрана гарантирует, что, по крайней мере, основное предположение одинаково для всех компиляторов, которые, по крайней мере, реализуют необходимые инструкции препроцессора для защиты.
  • В большинстве компиляторов #pragma once ускорит компиляцию (одного cpp), потому что компилятор не будет повторно открывать файл, содержащий эту инструкцию. Так что наличие его в файле может помочь или нет, в зависимости от компилятора. Я слышал, что g ++ может производить такую ​​же оптимизацию при обнаружении охранников, но это должно быть подтверждено.

Используя их вместе, вы получаете лучшее от каждого компилятора.

Теперь, если у вас нет какого-либо автоматического скрипта для создания охранников, может быть удобнее просто использовать #pragma один раз . Просто знайте, что это значит для переносимого кода. (Я использую VAssistX для быстрой генерации охранников и прагмы)

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

35
ответ дан 23 November 2019 в 00:33
поделиться

Обычно я не беспокоюсь о #pragma once , так как мой код иногда приходится компилировать с чем-то, кроме MSVC или GCC (компиляторы для встроенных систем не всегда есть #pragma).

Так что я все равно должен использовать #include охранников. Я также мог бы использовать #pragma once , как предлагают некоторые ответы, но, похоже, нет особых причин, и это часто вызывает ненужные предупреждения на компиляторах, которые его не поддерживают.

Я не уверен, какую экономию времени может принести прагма. Я слышал, что компиляторы обычно уже распознают, когда в заголовке нет ничего, кроме комментариев вне защитных макросов, и в этом случае будут выполнять эквивалент #pragma once (т. Е. Никогда не обрабатывать файл снова). Но я не уверен, что это

15
ответ дан 23 November 2019 в 00:33
поделиться

Думаю, первое, что вам нужно сделать, это проверить, действительно ли это имеет значение, т.е. вы должны сначала проверить производительность. Один из поисковых запросов в Google вызвал это .

На странице результатов столбцы для меня слегка отключены, но ясно, что по крайней мере до VC6 Microsoft не реализовывала оптимизацию защиты включения, которая другие инструменты использовали. Если защита включения была внутренней, это заняло в 50 раз больше времени по сравнению с внешней защитой включения (внешние средства защиты по крайней мере так же хороши, как #pragma). Но давайте рассмотрим возможные последствия этого:

Согласно представленным таблицам, время открытия включения и проверки в 50 раз больше, чем у эквивалента #pragma. Но фактическое время для этого было измерено в 1 микросекунду на файл еще в 1999 году!

Итак, сколько дублированных заголовков будет у одного TU? Это зависит от вашего стиля, но если мы скажем, что в среднем TU имеет 100 дубликатов, то в 1999 году мы потенциально платим 100 микросекунд за TU. С улучшением жестких дисков это, вероятно, значительно ниже, но даже тогда с предварительно скомпилированными заголовками и правильным отслеживанием зависимостей общая совокупная стоимость этого для проекта почти наверняка будет незначительной частью вашего времени сборки.

Теперь, с другой стороны, , как бы маловероятно это ни было, если вы когда-нибудь перейдете к компилятору, который не t support #pragma once затем подумайте, сколько времени потребуется, чтобы обновить всю вашу исходную базу, чтобы включить охранники, а не #pragma?

Нет причин, по которым Microsoft не может реализовать оптимизацию защиты включения так же, как GCC и любой другой компилятор (на самом деле, может ли кто-нибудь подтвердить, реализуют ли это его более свежие версии?). IMHO, #pragma once мало что делает, кроме ограничения вашего выбора альтернативного компилятора.

9
ответ дан 23 November 2019 в 00:33
поделиться

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

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

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

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

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

4
ответ дан 23 November 2019 в 00:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: