Jedną trudnością związaną z automatycznym wykluczaniem duplikatów nagłówków jest to, że standard C relatywnie milczy na temat tego, co oznaczają nazwy plików. Załóżmy na przykład, że kompilowany plik główny zawiera dyrektywy #include "f1.h"
i #include "f2.h"
, a pliki znalezione dla tych dyrektyw zawierają oba #include "f3.h"
. Jeśli f1.h
i f2.h
znajdują się w różnych katalogach, ale zostały znalezione podczas wyszukiwania ścieżek dołączania, wówczas nie byłoby jasne, czy #include
dyrektywy w tych plikach miały ładować ten sam f3.h
plik lub różne.
Sytuacja staje się jeszcze gorsza, jeśli dodaje się możliwości dołączania plików, w tym ścieżek względnych. W niektórych przypadkach, w których pliki nagłówkowe używają ścieżek względnych dla zagnieżdżonych dyrektyw zawierających, i gdy chce się uniknąć wprowadzania jakichkolwiek zmian w dostarczonych plikach nagłówkowych, może być konieczne zduplikowanie pliku nagłówkowego w wielu miejscach w strukturze katalogów projektu. Mimo że istnieje wiele fizycznych kopii tego pliku nagłówka, należy je traktować semantycznie, jakby były pojedynczym plikiem.
Jeśli #pragma once
dyrektywa zezwala na podążanie za identyfikatorem once
, z semantyką, że kompilator powinien pominąć plik, jeśli identyfikator odpowiada jednemu z wcześniej napotkanej #pragma once
dyrektywy, to semantyka byłaby jednoznaczna; kompilator, który mógłby stwierdzić, że #include
dyrektywa załaduje ten sam #pragma once
plik ze znacznikami jak wcześniejszy, może zaoszczędzić trochę czasu, pomijając plik bez ponownego otwierania go, ale takie wykrycie nie będzie semantycznie ważne, ponieważ plik zostanie pominięty, czy lub nie nazwa pliku została rozpoznana jako pasująca. Nie znam jednak żadnych kompilatorów działających w ten sposób. Posiadanie kompilatora obserwuje, czy plik pasuje do wzorca #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
i traktuje taką rzecz jako równoważną powyższemu #pragma once someIdentifier
ifsomeIdentifier
pozostaje zdefiniowany, jest zasadniczo tak dobry.
#pragma once
kompilator, który dołącza ten plik tylko raz.