Ich weiß es, um mehrere Aufnahme von Header-Datei zu verhindern. Aber angenommen, ich stelle sicher, dass ich diese Datei nur einmal in eine CPP-Datei aufnehmen werde. Gibt es noch Szenarien, in denen ich diese Sicherheit benötigen würde?Zweck von #ifndef FILENAME .... # endif in Header-Datei
Antwort
können Sie garantieren, dass Ihre Code nur einmal enthält, aber können Sie garantieren, dass jemand ‚s-Code einmal enthalten wird?
Darüber hinaus vorstellen, dass diese:
// a.h
typedef struct { int x; int y; } type1;
// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;
// main.c
#include "a.h"
#include "b.h"
Oh, nein! Unsere main.c
nur jeweils einmal enthalten, aber b.h
enthält a.h
, so haben wir zweimal, trotz unserer besten Bemühungen a.h
.
ich nun vor, diese versteckte hinter drei oder mehr Schichten von #include
s und es ist ein kleinerer interner Gebrauch-nur-Header, der zweimal aufgenommen wird und es ist ein Problem, weil eine des Header #undef
einen Makro ed, dass es definiert, aber den zweiten Kopf #define
d es wieder und brach einige Code und es dauert ein paar Stunden, um herauszufinden, warum es widersprüchliche Definitionen der Dinge gibt.
Nein, das ist der einzige Zweck der Include-Wächter, aber ihre Verwendung sollte ein Kinderspiel sein: Es braucht wenig Zeit und spart möglicherweise viel.
Das ist seine einzige Raison d'etre. Es ist immer noch eine gute Idee, auch wenn Sie denken, dass Sie das abgedeckt haben; Es verlangsamt nicht Ihren Code oder irgendetwas, und es tut nie weh, eine zusätzliche Wache zu haben.
Der Zweck des Schutzes besteht darin, zu verhindern, dass die Datei zu in derselben CPP-Datei mehr als einmal enthalten ist. Es schützt nicht vor dem Einschließen der Datei in mehr als einer CPP-Datei.
Wenn Sie sicher sind, dass eine Headerdatei nicht in einer anderen Headerdatei enthalten ist, ist der Guard nicht erforderlich. aber es ist immer noch eine gute Form.
noch bessere Form ist
#pragma once
zu verwenden, wenn Ihr Compiler unterstützt wird.
Der include guard ist besser IMHO, weil es tragbarer ist. Ich verlasse mich nicht auf kompilerspezifische Merkmale wie die Pest. –
@Chris: Portabilität zählt für Open Source Code. Aber normalerweise nicht für geschlossene Quellen. #pragma ist einmal zuverlässiger und schneller als Wächter, da der Compiler _skip_ die Datei erneut scannen kann. Das ist die Sache, die in einem Closed-Source-Laden wirklich zählt. –
GCC optimiert das Include-Guard-Idiom, um im Wesentlichen dasselbe zu tun. Aber ich stimme zu, dass '#pragma once' für eine Closed-Source-Codebase, die Visual Studio verwendet, ziemlich gut ist. –
Sicherzustellen, dass Ihr Code nur einmal enthalten ist, ist der einzige Zweck eines so genannten "Header Guard".
Dies kann nützlich sein, als ob irgendwo zwischen Ihren Header-Dateien eine zirkuläre Abhängigkeit besteht, Sie werden nicht in einer endlosen Schleife von Dateien eingeschlossen.
Das zusätzliche Szenario, das ich mir vorstellen kann (und wir taten es), ist C++ Mocks zu erstellen.
Sie explizit in Ihrem Build definieren die Datei GUARD-Wert und dann können Sie Ihre eigene Mock Realisation über -include my_mock.h als die zusätzliche Compiler-Option (wir verwendeten g ++).
my_mock.h
#define THAT_FILE_GUARD
class ThatClass
{
void connect()
{
std::cout << "mock connect" << std::endl;
}
}
einen Kopf guard Mit wie diese den Übersetzungsvorgang beschleunigt, stellen drei Quelldateien mit dem Header (minus der Kopfschutz), das wiederum würde bedeuten, würde der Compiler enthalten haben den Header (Parsen und lexing die Syntax) mehrere Male vorbei.
Mit einem Header-Guard wird der Compiler sagen: "Ha! Ich habe das vorher gesehen, und nein, ich werde die Syntax nicht analysieren/lexen und dadurch den Kompiliervorgang beschleunigen.
Hoffen, dass dies hilft, Mit freundlichen Grüßen, Tom.
- 1. Best-Practice auf C-Header-Dateien mit #ifndef #define #endif
- 2. In C und C++, warum ist jede .h-Datei normalerweise mit #ifndef #define #endif -Direktiven umgeben?
- 3. Warum werden #ifndef und #define in C++ - Headerdateien verwendet?
- 4. wenn {} in if: endif
- 5. Sind Tokens nach #endif legal?
- 6. Warum funktioniert mein ifndef-Abschnitt nicht?
- 7. benötigen Klärung #ifndef #define
- 8. wie man filename von file_id in telegramm
- 9. Get filename von wget in php
- 10. Schnelle Frage in Bezug auf bedingte Compilation (ifndef)
- 11. #ifndef funktioniert nur für "Deklaration" Teile?
- 12. Node/Multer Get Filename
- 13. awk - display filename
- 14. Zweck von {- # # -} in Haskell
- 15. Angular FormData filename encoding
- 16. Obj-C, unter Verwendung von ifndef und target-Parameter, um nur Debug-Zeilen zu drucken?
- 17. Verwendet #ifndef und #define in C++ veraltet?
- 18. Get filename von tmpfile() unter Windows
- 19. #ifdef #else #endif Makro Frage
- 20. Return Filename bei Verwendung von Openfile
- 21. Endif-Anweisung wird nicht durchlaufen
- 22. Fehler beim Kompilieren der Headerdatei mit einer Map vom Typ map <string, struct>
- 23. if/endif "Unerreichbarer Code erkannt" in C#
- 24. Vim: Springen zu, wenn endif in Fortran
- 25. Codeblocks C Projekt - Headerdatei redundant? (Warum wird das Projekt nicht benötigt?)
- 26. Codeblöcke zwischen #if 0 und #endif müssen doppelte Anführungszeichen enthalten?
- 27. Zweck von pyVim in pyVmomi
- 28. Zweck von @ Symbolen in Python?
- 29. Umbenennen von Dateien mit Hinzufügen einer Nummer in bash filename
- 30. Filename oder Objekt von UIImage zur Verarbeitung in Obj-C
Danke allen. Chris bekommt es, weil es ausgearbeitet ist :) – deeJ
Nächstes Mal, wenn ich meine Rep-Kappe brechen muss, werde ich nur daran denken, zu posten, während ich meine Hausaufgaben aufschiebe. :) –