Include guard
Nas linguagens de programação C e C++, uma include guard, às vezes chamada de macro guard ou header guard, é uma construção usada para evitar o problema da dupla inclusão ao lidar com a diretiva "include". A adição de #include guards em um arquivo cabeçalho é uma forma de tornar esse arquivo idempotente.
Imagem: Lawrence OP · BY-NC · Openverse
O seguinte código em C demonstra um problema real que pode surgir se #include guards estão faltando: Aqui, o arquivo "crianca.c" incluiu indiretamente duas cópias do texto no arquivo cabeçalho "avo.h". Isto provoca um erro de compilação, já que a estrutura do tipo foo vai acabar sendo definida duas vezes. Em C++, isso seria uma violação da One Definition Rule (ou "regra da definição única," em tradução livre).
Imagem: Defence Images · BY-SA · Openverse
Aqui, a primeira inclusão de "avo.h" faz com que a macro AVO_H seja definida. Em seguida, quando "crianca.c" inclui "avo.h" pela segunda vez, o teste do #ifndef retorna falso, e o pré-processador salta para baixo até o #endif, evitando, assim, a segunda definição de structfoo. O programa é compilado corretamente. Diferentes convenções de nomenclatura para macros de guarda podem ser usadas por programadores diferentes. Outras formas comuns de exemplo acima incluem AVO_INCLUDED, NOMEDOCRIADOR_AAAAMMDD_HHMMSS (com a data apropriada substituída), e nomes gerados a partir de um UUID. (No entanto, nomes que começam com um ou dois underscores, como _AVO_H e __AVO_H, são reservados para a implementação e não devem ser usados pelo usuário.) Claro, é importante evitar a duplicação do mesmo nome de uma include guard em diferentes arquivos cabeçalho, pois incluir o 1º vai impedir que o 2º seja incluído, levando a perda de quaisquer declarações, definições inline, ou outros #includes no 2º cabeçalho.
Imagem: DVIDSHUB · BY · Openverse
Para que #include guards funcionem corretamente, cada guarda tem que testar e definir macros de pré-processador diferentes, condicionalmente. Portanto, um projeto usando #include guards deve criar um esquema coerente de atribuição de nomes para suas include guards, e certificar-se de que seu esquema não entra em conflito com quaisquer cabeçalhos usados de terceiros, ou com os nomes de quaisquer macros globalmente visíveis. Por esta razão, a maioria das implementações de C e C++ fornecem uma diretiva não-padrão #pragma once. Esta diretiva, inserida na parte superior de um arquivo cabeçalho, irá garantir que o arquivo é incluído apenas uma vez. A linguagem Objective-C (que é um superconjunto de C) introduziu uma diretiva #import que funciona exatamente como #include, exceto que inclui cada arquivo apenas uma vez, eliminando assim a necessidade de #include guards.


