Uma dificuldade com a exclusão automática de cabeçalho duplicado é que o padrão C é relativamente silencioso quanto ao significado dos nomes de arquivos incluídos. Por exemplo, suponha que o arquivo principal que está sendo compilado contenha diretivas #include "f1.h"
e #include "f2.h"
, e os arquivos encontrados para essas diretivas contenham #include "f3.h"
. Se f1.h
e f2.h
estiver em diretórios diferentes, mas foram encontrados pela pesquisa de caminhos de inclusão, não seria claro que as #include
diretivas desses arquivos foram destinadas a carregar o mesmo f3.h
arquivo ou diferentes.
As coisas pioram ainda mais se adicionarmos as possibilidades de incluir arquivos, incluindo caminhos relativos. Em alguns casos em que os arquivos de cabeçalho usam caminhos relativos para diretivas de inclusão aninhadas, e onde se deseja evitar alterações nos arquivos de cabeçalho fornecidos, pode ser necessário duplicar um arquivo de cabeçalho em vários locais na estrutura de diretórios de um projeto. Embora existam várias cópias físicas desse arquivo de cabeçalho, elas devem ser consideradas semanticamente como se fossem um único arquivo.
Se a #pragma once
diretiva permitisse que um identificador seguisse once
, com a semântica que o compilador deve ignorar o arquivo se o identificador corresponder a um de uma #pragma once
diretiva encontrada anteriormente , a semântica seria inequívoca; um compilador que poderia dizer que uma #include
diretiva carregaria o mesmo #pragma once
arquivo marcado como um anterior, poderia economizar um pouco de tempo ignorando o arquivo sem abri-lo novamente, mas essa detecção não seria semanticamente importante, pois o arquivo seria ignorado se ou não, o nome do arquivo foi reconhecido como uma correspondência. No entanto, não conheço nenhum compilador trabalhando dessa maneira. Ter um compilador observando se um arquivo corresponde ao padrão #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
e tratando algo equivalente ao acima #pragma once someIdentifier
sesomeIdentifier
permanece definido, é essencialmente tão bom.
#pragma once
que diz ao compilador para incluir apenas esse arquivo uma vez.