Одна проблема с автоматическим исключением дублирующихся заголовков состоит в том, что стандарт C относительно не говорит о том, что означают имена файлов. Например, предположим, что основной компилируемый файл содержит директивы #include "f1.h"
и #include "f2.h"
, и файлы, найденные для этих директив, содержат #include "f3.h"
. Если f1.h
и f2.h
находятся в разных каталогах, но были найдены путем поиска путей включения, то было бы неясно , какие #include
директивы в этих файлах предназначены для загрузки одного и того же f3.h
файла или разных.
Ситуация становится еще хуже, если добавить возможности включения файлов, включая относительные пути. В некоторых случаях, когда в файлах заголовков используются относительные пути для вложенных директив include, и если желательно избежать внесения каких-либо изменений в предоставленные файлы заголовков, может потребоваться дублирование файла заголовка в нескольких местах в структуре каталогов проекта. Даже если существует несколько физических копий этого заголовочного файла, их следует рассматривать семантически, как если бы они были одним файлом.
Если #pragma once
директива позволила идентификатору следовать once
, с семантикой, которую компилятор должен пропускать файл, если идентификатор совпадает с идентификатором из ранее встречавшейся #pragma once
директивы, то семантика была бы однозначной; компилятор, который мог бы сказать, что #include
директива загрузит тот же #pragma once
файл с тегами, что и предыдущий, он мог бы сэкономить немного времени, пропуская файл, не открывая его снова, но такое обнаружение не было бы семантически важным, поскольку файл будет пропущен или не имя файла было распознано как совпадение. Однако я не знаю ни о каких компиляторах, работающих таким образом. Наличие компилятора, наблюдающего, соответствует ли файл шаблону, #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
и рассматривающего такую вещь как эквивалент вышеупомянутого, #pragma once someIdentifier
еслиsomeIdentifier
остается определенным, по существу, так же хорошо.
#pragma once
который говорит компилятору включать этот файл только один раз.