#ifndef Inclure les gardes dans C

Jinku Hu 12 octobre 2023
  1. Utiliser ifndef pour protéger contre l’inclusion multiple de fichiers d’en-tête dans le langage C
  2. Utiliser la directive ifndef pour s’assurer que les macros ne sont pas définies plusieurs fois dans C
#ifndef Inclure les gardes dans C

Cet article démontrera les multiples méthodes d’utilisation de la #ifndef, y compris les gardes en C.

Utiliser ifndef pour protéger contre l’inclusion multiple de fichiers d’en-tête dans le langage C

Les fichiers d’en-tête en C sont utilisés pour définir l’interface des fonctions implémentées dans le fichier source du même nom. L’interface comprend généralement des prototypes de fonctions, des définitions de structures de données accessibles au public, et quelques autres éléments divers.

Notez que les fichiers d’en-tête peuvent être inclus dans le fichier source plusieurs fois, ce qui entraîne des erreurs de compilation. Habituellement, cela est évité grâce à la directive de préprocesseur #ifndef, qui est appelée wrapper #ifndef. Lorsque le contenu du fichier d’en-tête est inclus dans la structure montrée dans l’exemple suivant, où la directive #ifndef MY_GUARD est le point de départ et #endif la fin. La directive ifndef vérifie si la macro MY_GUARD est définie, sinon elle continue et la définit avec la directive suivante. Dans le cas où l’utilisateur inclut le même en-tête pour la seconde fois, la directive ifndef évaluera false et ignorera le code avant la directive #endif. En conséquence, le compilateur n’obtiendra qu’une seule copie du code de ce fichier d’en-tête et le traduira avec succès.

#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

Une autre méthode pour obtenir les mêmes résultats est d’inclure la directive #pragma once dans le fichier d’en-tête. Le préprocesseur n’analyse ces fichiers d’en-tête qu’une seule fois et garantit qu’ils ne seront pas lus à nouveau. L’un des inconvénients de la méthode suivante est qu’elle présente une faible portabilité entre les différents préprocesseurs, et il est donc préférable de conserver la méthode wrapper #ifndef pour assurer une meilleure flexibilité de la base de code.

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

Utiliser la directive ifndef pour s’assurer que les macros ne sont pas définies plusieurs fois dans C

On peut aussi utiliser la directive ifndef pour vérifier si l’expression macro donnée a déjà été définie. La logique fonctionne exactement comme dans l’exemple précédent ; si l’expression n’est pas définie, la directive # define suivante est traitée en conséquence. La seule ligne entre la directive #ifndef et la directive #endif est une définition de macro, ce qui signifie que si la condition est fausse, seule la définition de la macro donnée est ignorée.

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