Разница между прагмой внутри и снаружи включает охрану?

StackOverflow https://stackoverflow.com/questions/5382404

  •  28-10-2019
  •  | 
  •  

Вопрос

Есть ли разница между размещением #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), поскольку я решил объединить оба (прагму и защиту заголовка) в своем коде.

РЕДАКТИРОВАТЬ:

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

Это было полезно?

Решение

Есть тонкая разница в этом, если 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. Это зависит от реализации.

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

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

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

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

Другие советы

Они излишни.

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

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

Дело 1:

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

Случай 2:

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

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

Ваше здоровье

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top