#ifndef Includi protezioni in C

Jinku Hu 12 ottobre 2023
  1. Usa ifndef Include Guard per proteggerti dall’inclusione multipla di file di intestazione in C
  2. Usa la direttiva ifndef per assicurarti che le macro non vengano definite più volte in C
#ifndef Includi protezioni in C

Questo articolo dimostrerà diversi metodi su come utilizzare #ifndef, incluse le guardie in C.

Usa ifndef Include Guard per proteggerti dall’inclusione multipla di file di intestazione in C

I file di intestazione in C vengono utilizzati per definire l’interfaccia per le funzioni implementate nel file di origine con lo stesso nome. L’interfaccia di solito include prototipi di funzioni, definizioni per strutture di dati accessibili pubblicamente e altre cose varie.

Si noti che i file di intestazione possono essere inclusi più volte nel file di origine, causando errori del compilatore. Di solito, questo viene evitato con la direttiva del preprocessore #ifndef, che si chiama wrapper #ifndef. Quando il contenuto del file di intestazione è racchiuso nella struttura mostrata nel seguente esempio, dove la direttiva #ifndef MY_GUARD è il punto di partenza e #endif la fine. La direttiva ifndef controlla se la macro MY_GUARD è definita, in caso contrario continua e la definisce con la direttiva successiva. Nel caso in cui l’utente includa la stessa intestazione per la seconda volta, la direttiva ifndef valuterà false e ignorerà il codice prima della direttiva #endif. Di conseguenza, il compilatore otterrà solo una copia del codice da questo file di intestazione e lo tradurrà correttamente.

#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

Un altro metodo per ottenere gli stessi risultati è includere la direttiva #pragma once nel file di intestazione. Il preprocessore analizza i file di intestazione solo una volta e garantisce che non vengano letti di nuovo. Uno svantaggio del metodo seguente è che ha una bassa portabilità tra i diversi preprocessori, quindi si potrebbe voler restare con il metodo wrapper #ifndef per garantire una migliore flessibilità della base di codice.

#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;
}

Usa la direttiva ifndef per assicurarti che le macro non vengano definite più volte in C

In alternativa, possiamo usare la direttiva ifndef per verificare se l’espressione macro data è già stata definita. La logica funziona esattamente come nell’esempio precedente; se l’espressione non è definita, la successiva direttiva #define viene elaborata di conseguenza. L’unica linea tra #ifndef e #endif è una definizione di macro, il che significa che nel caso in cui la condizione sia falsa, viene saltata solo la macro data di definizione.

#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);
}
Autore: 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