- Include Guard
-
Der Include Guard (dt: Include Wächter) ist eine Programmiertechnik, um in C oder C++ das Problem der doppelten Einbindung (engl.: double inclusion) zu umgehen.
Dieses Problem tritt auf, wenn innerhalb eines Moduls mehrfach die gleiche Header-Datei eingebunden wird. Das geschieht in der Regel unbeabsichtigt, zum Beispiel wenn mehrere Header-Dateien die gleiche Bibliothek benutzen.
Inhaltsverzeichnis
Beispiel
// A.h const int M = 123; class A { /* ... */ };
// B.h #include "A.h" class B : public A { /* ... */ };
Im Hauptprogramm möchte man nun sowohl die Klasse A als auch B nutzen:// program.c #include "A.h" #include "B.h" int main() { /* ... */ }
Der Compiler liefert einen Fehler, weil eine Klasse oder Variable nochmals definiert wird (engl.: redefinition).
#ifndef Wrapper (oder Makro-Guard)
Der #ifndef-Wrapper ist der traditionelle und C-konforme Ansatz. Er versucht das Problem zu lösen, indem er ein eindeutiges Makro beim ersten Einbinden der Header-Datei definiert. Ist dieses Makro bereits definiert, werden die Definitionen des Headers übersprungen:
// A.h #ifndef _A_H_ #define _A_H_ class A { /* ... */ }; #endif /* _A_H_ */
Im obigen Beispiel bewirkt das, dass beim erstmaligen Einbinden von A.h (aus program.cpp) das Makro _A_H_ noch nicht definiert ist und der Präprozessor die Definitionen durchläuft. Beim zweiten Einbinden (aus B.h) ist das Makro bereits definiert und der Präprozessor überspringt den #ifndef .. #endif-Block.
Das eigentliche Problem mit dieser Technik ist die sog. namespace pollution: die definierten Makros liegen im globalen Namensraum und „verschmutzen“ diesen mit steigender Anzahl zusehends. Dem kann durch die Festlegung von Namenskonventionen zwar vorgebeugt werden, dies löst das Problem jedoch nicht[1].
Der CPP, der Präprozessor des GCC, erkennt solche Konstrukte automatisch, merkt sich die entsprechenden Dateien und überspringt diese bei nochmaligem Einbinden[2].
#pragma Guard
Sowohl der Microsoft C/C++ Compiler[3] als auch der GCC[4] unterstützen heute die Präprozessor-Direktive #pragma once. Diese sorgt ebenfalls dafür, dass eine (Header-)Datei nur einmalig eingebunden wird, setzt jedoch auf höherer Ebene an (direkt am Präprozessor) und führt auch keine Makros in den globalen Namensraum ein.
Zur Verwendung genügt es innerhalb der Header-Datei die Anweisung #pragma once einzufügen:
// A.h #pragma once class A { /* ... */ };
Gerade bei portablem Code muss jedoch beachtet werden, dass dies eine Compiler-spezifische Erweiterung ist und nicht zwingend von jedem C/C++-Compiler unterstützt wird[4].
Siehe auch
- Include Guard im englischen Wikibooks.
Einzelnachweise
- ↑ Eric Fleegal's WebLog on MSDN Blogs. Abgerufen am 19. August 2011.
- ↑ Once-Only Headers im GNU CPP Online Manual. Abgerufen am 19. August 2011.
- ↑ MSDN Visual Studio 2010 - once
- ↑ a b Alternatives to Wrapper #ifndef im GNU CPP Online Manual. Abgerufen am 19. August 2011.
Kategorien:- Programmiersprache C
- Programmiersprache C++
Wikimedia Foundation.