#ifndef Inclui guardas em C

Jinku Hu 12 outubro 2023
  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
#ifndef Inclui guardas 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);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook