Одна проблема с автоматическим исключением дублирующихся заголовков состоит в том, что стандарт 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который говорит компилятору включать этот файл только один раз.