#ifndef Include-Guards in C

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie den ifndef Include-Guard, um sich vor dem mehrfachen Einbinden von Header-Dateien in C zu schützen
  2. Verwenden Sie die ifndef-Direktive, um sicherzustellen, dass Makros nicht mehrfach in C definiert werden
#ifndef Include-Guards in C

Dieser Artikel demonstriert mehrere Methoden, wie man #ifndef Include-Guards in C verwendet.

Verwenden Sie den ifndef Include-Guard, um sich vor dem mehrfachen Einbinden von Header-Dateien in C zu schützen

Header-Dateien in C werden verwendet, um die Schnittstelle für die Funktionen zu definieren, die in der gleichnamigen Quelldatei implementiert sind. Die Schnittstelle enthält in der Regel Funktionsprototypen, Definitionen für öffentlich zugängliche Datenstrukturen und einige andere verschiedene Dinge.

Beachten Sie, dass Header-Dateien unter Umständen mehrfach in der Quelldatei enthalten sind, was zu Compiler-Fehlern führt. Normalerweise wird dies mit der Präprozessor-Direktive #ifndef verhindert, die als Wrapper #ifndef bezeichnet wird. Wenn der Inhalt der Header-Datei in die im folgenden Beispiel gezeigte Struktur eingeschlossen ist, wobei die Direktive #ifndef MY_GUARD den Anfangspunkt und #endif den Endpunkt bildet. Die Direktive ifndef prüft, ob das Makro MY_GUARD definiert ist, wenn nicht, fährt sie fort und definiert es mit der nächsten Direktive. Falls der Benutzer denselben Header zum zweiten Mal einfügt, wertet die ifndef-Direktive false aus und ignoriert den Code vor der #endif-Direktive. Als Ergebnis wird der Compiler nur eine Kopie des Codes aus dieser Header-Datei erhalten und diesen erfolgreich übersetzen.

#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

Eine andere Methode, um das gleiche Ergebnis zu erzielen, besteht darin, die Direktive #pragma once in die Header-Datei aufzunehmen. Der Präprozessor scannt diese Header-Dateien nur einmal und garantiert, dass sie nicht noch einmal gelesen werden. Ein Nachteil der folgenden Methode ist, dass sie eine geringe Portabilität über die verschiedenen Präprozessoren hinweg aufweist, so dass man vielleicht bei der Wrapper-Methode #ifndef bleiben möchte, um eine bessere Flexibilität der Codebasis zu gewährleisten.

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

Verwenden Sie die ifndef-Direktive, um sicherzustellen, dass Makros nicht mehrfach in C definiert werden

Alternativ können wir die ifndef-Direktive verwenden, um zu prüfen, ob der angegebene Makro-Ausdruck bereits definiert wurde. Die Logik funktioniert genau wie im vorherigen Beispiel; wenn der Ausdruck nicht definiert ist, wird die nächste #define-Direktive entsprechend verarbeitet. Die einzige Zeile zwischen #ifndef und #endif ist eine Makrodefinition, was bedeutet, dass im Falle, dass die Bedingung falsch ist, genau die gegebene Makrodefinition übersprungen wird.

#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