Разница между прагмой однажды внутри и снаружи включает охранников? - PullRequest
10 голосов
/ 21 марта 2011

Есть ли какая-либо разница между размещением #pragma once внутри защитных ограждений, а не снаружи?

дело 1:

#ifndef SOME_HEADER_H
#define SOME_HEADER_H
#pragma once

дело 2:

#pragma once
#ifndef SOME_HEADER_H
#define SOME_HEADER_H

Мне просто интересно из любопытства, есть ли какие-либо особые случаи, когда я бы предпочел один или другой (случай 1 или случай 2), поскольку я решил объединить оба (прагма и защита заголовков) в моем коде.

EDIT:

Я думаю, что вы, ребята, неправильно истолковываете мой вопрос ... Я спрашиваю о местонахождении pragma once, а не прагмы -vs- охранников заголовка.

Ответы [ 3 ]

6 голосов
/ 22 марта 2011

Существует небольшая разница в том, что если SOME_HEADER_H уже определено до включения заголовка, то во втором случае препроцессор обработает #pragma once, а в первом случае - нет.

Вы увидите функциональную разницу, если вы #undef SOME_HEADER_H включите файл снова с тем же TU:

#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"

Теперь, в случае 1 у меня есть все определения из файла заголовка.В случае 2 я не знаю.

Даже без #undef вы могли бы видеть разницу во времени предварительной обработки из-за игнорирования #pragma once в случае 1. Это зависит от реализации.

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

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

Используется ожидаемым образом, однако нет никакой разницы при условии, что реализация обрабатывает #pragma once в том смысле, в котором ее определяет Microsoft.Пока он обрабатывается, а не пропускается, он помечает содержащий файл для оптимизации, поэтому не имеет значения, будет ли он обрабатываться при втором проходе через файл - второй проход не произойдет.

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

5 голосов
/ 21 марта 2011

Они являются избыточными.

#pragma once поддерживается не всеми компиляторами, в то время как включены средства защиты.Просто используйте включить охранников.Компиляторы, такие как gcc, достаточно умны, чтобы понять, что такое защита, и даже не открывать файл снова.

1 голос
/ 22 марта 2011

Чтобы ответить на ваш вопрос:

Случай 1:

Компилятор проверит, установлена ​​или нет константа препроцессора, если не определит ее, а затем проверит директиву #pragma ońce.Скорее всего, это поиск по хешу в строке "SOME_HEADER_H", чтобы узнать, определен ли он или нет, прежде чем выполнять другой поиск по хешу по текущему имени файла (вероятно, константу __ FILE __, установленную препроцессором).Поэтому, если файл никогда не читался, у нас есть два поиска хешей и два сохранения хешей, если файл был прочитан только одним поиском хеша.

Случай 2:

Это, очевидно,то же самое, что и в случае 1, но в обратном порядке.Таким образом, единственное, что мы можем сравнить, - это длина хеш-ключей для использования в качестве поиска.В зависимости от пути к текущему заголовочному файлу, то есть длины пути, поиск хеша для директивы #pragma Once может быть более дорогим для вычисления.Если имя файла «C: \ dude.h», оно короче, чем «SOME_HEADER_H».

Так что я думаю, в итоге.Нет. Нет особого случая, когда Случай 1 был бы более выгодным, чем Случай 2 или наоборот.По крайней мере, не кричать Эврика кончено;)

Ура

...