Una difficoltà con l'esclusione automatica dell'intestazione dei duplicati è che lo standard C è relativamente silenzioso sul tema di ciò che significa che i nomi dei file includono. Ad esempio, supponiamo che il file principale da compilare contenga le direttive #include "f1.h"
e #include "f2.h"
, e che i file trovati per tali direttive contengano entrambi #include "f3.h"
. Se f1.h
e f2.h
sono in directory diverse, ma sono stati trovati cercando i percorsi di inclusione, non sarebbe chiaro che le direttive #include
all'interno di quei file fossero intese per caricare lo stesso file f3.h
, o diversi.
Le cose peggiorano ulteriormente se si aggiunge la possibilità di includere i file, compresi i percorsi relativi. In alcuni casi in cui i file di intestazione utilizzano percorsi relativi per le direttive di inclusione nidificata e dove si desidera evitare di apportare modifiche ai file di intestazione forniti, potrebbe essere necessario duplicare un file di intestazione in più punti all'interno della struttura di directory di un progetto. Anche se esistono più copie fisiche di quel file di intestazione, dovrebbero essere considerate semanticamente come se fossero un singolo file.
Se la direttiva #pragma once
ha permesso a un identificatore di seguire once
, con la semantica che il compilatore dovrebbe saltare il file se l'identificatore corrisponde a una direttiva #pragma once
incontrata in precedenza, la semantica non sarebbe ambigua; un compilatore che potrebbe dire che una direttiva #include
avrebbe caricato lo stesso file con #pragma once
-tagged come una precedente, potrebbe risparmiare un po 'di tempo saltando il file senza aprirlo di nuovo, ma tale rilevamento non sarebbe semanticamente importante dal il file sarebbe saltato indipendentemente dal fatto che il nome del file fosse riconosciuto o meno come una corrispondenza. Tuttavia, non sono a conoscenza di alcun compilatore che lavori in quel modo. Avere un compilatore osserva se un file corrisponde al modello #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
e il trattamento di una cosa equivalente al precedente #pragma once someIdentifier
se someIdentifier
rimane definito, è essenzialmente buono.