#ifndef Inclui guardas em C

  1. Use ifndef Incluir Proteção para Proteger Contra Inclusão Múltipla de Arquivos de Cabeçalho em C
  2. Use a diretiva ifndef para garantir que as macros não sejam definidas várias vezes em C

Este artigo demonstrará vários métodos de como usar #ifndef incluir protetores em C.

Use ifndef Incluir Proteção para Proteger Contra Inclusão Múltipla de Arquivos de Cabeçalho em C

Arquivos de cabeçalho em C são usados para definir a interface para as funções implementadas no arquivo de origem com o mesmo nome. A interface geralmente inclui protótipos de funções, definições para estruturas de dados acessíveis ao público e algumas outras coisas diversas.

Observe que os arquivos de cabeçalho podem ser incluídos no arquivo de origem várias vezes, levando a erros do compilador. Normalmente, isso é evitado com a diretiva de pré-processador #ifndef, que é chamada de wrapper #ifndef. Quando o conteúdo do arquivo de cabeçalho está contido na estrutura mostrada no exemplo a seguir, onde a diretiva #ifndef MY_GUARD é o ponto de partida e #endif o final. A diretiva ifndef verifica se a macro MY_GUARD está definida, senão continua e a define com a próxima diretiva. Caso o usuário inclua o mesmo cabeçalho pela segunda vez, a diretiva ifndef será avaliada como falsa e ignorará o código antes da diretiva #endif. Como resultado, o compilador obterá apenas uma cópia do código desse arquivo de cabeçalho e o traduzirá com êxito.

#include <stdio.h>

#ifndef MY_GUARD
#define MY_GUARD 1

#define  PER(D) #D
#define  JOIN(A,B) (A ## B)
#define  JOINX(A,B) JOIN(A,B)

int power(int base, int n) {
    int p = base;
    for (size_t i = 0; i < n; i++) {
      p *= base;
    }
    return p;
}
#endif

Outro método para obter os mesmos resultados é incluir a diretiva #pragma once no arquivo de cabeçalho. O pré-processador verifica esses arquivos de cabeçalho apenas uma vez e garante que eles não sejam lidos novamente. Uma desvantagem do método a seguir é que ele tem baixa portabilidade entre os diferentes pré-processadores, então pode-se querer usar o método #ifndef do wrapper para garantir melhor flexibilidade da base de código.

#include <stdio.h>

#pragma once

#define  PER(D) #D
#define  JOIN(A,B) (A ## B)
#define  JOINX(A,B) JOIN(A,B)

int power(int base, int n) {
    int p = base;
    for (size_t i = 0; i < n; i++) {
      p *= base;
    }
    return p;
}

Use a diretiva ifndef para garantir que as macros não sejam definidas várias vezes em C

Alternativamente, podemos usar a diretiva ifndef para verificar se a expressão macro fornecida já foi definida. A lógica funciona exatamente como no exemplo anterior; se a expressão não for definida, a próxima diretiva #define é processada de acordo. A única linha entre #ifndef e #endif é uma definição de macro, o que significa que, no caso de a condição ser falsa, apenas a definição de macro fornecida é ignorada.

#include <stdio.h>
#include <stdlib.h>

#define  PER(D) #D

#ifndef DLEVEL
#define DLEVEL 6
#endif

int main() {

    for (int j = 0; j < DLEVEL; ++j) {
        printf("%s\n", PER(stringify this));
    }

    exit(EXIT_SUCCESS);
}