Ответ 1
Там тонкая разница в том, что если 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
, и вы внимательно изучите ее документацию, вы можете найти окончательное утверждение о том, применяется ли оптимизация по пути, по которому этот файл включен, или путем сравнения чего-то, что идентифицирует хранилище файлов, как индекс inode. Если последнее, вы даже можете выяснить, есть ли еще мошенники, которые можно было бы вытащить, чтобы обмануть препроцессор, например удаленный монтаж локальной файловой системы, чтобы скрыть, что он "тот же файл действительно"...
Используемый в ожидаемом режиме, однако, нет никакой разницы при условии, что реализация рассматривает #pragma once
так, как это определяет Microsoft. Пока он обрабатывается, а не пропускается, он маркирует содержащийся файл для оптимизации, поэтому не имеет значения, будет ли он обрабатываться на втором проходе через файл - второго прохода не будет.
И, конечно, поскольку прагма является нестандартной, по крайней мере теоретически она может иметь совершенно другое значение для разных реализаций, и в этом случае это может иметь значение, когда и сколько раз она обрабатывается. На практике вы думаете, что никто не сделает этого.