2012-11-12 10 views
33

enter image description hereSollte ich #include guards UND #pragma noch einmal verwenden?

http://en.wikipedia.org/wiki/Pragma_once
Sollte ich noch Wachen verwenden sind, wenn alle diese Compiler #pragma once unterstützen?
Viele Antworten auf Stack-Überlauf sagen, beide für die Kompatibilität zu verwenden, aber ich bin mir nicht sicher, ob das immer noch wahr klingt. Welche Compiler unterstützen heute nicht #pragma once?

Ich bin mir nicht sicher, ob die Verwendung beider war nur eine Empfehlung, bevor es widley adoptiert wurde, oder wenn es immer noch sehr gute Gründe gibt, beide Methoden zu verwenden.
Alle Beispiele, in denen nur die Verwendung von #pragma once Probleme verursacht?

+11

Denken Sie daran, dass ältere Versionen der aufgelisteten Compiler dies möglicherweise nicht unterstützen. Wenn Sie also ein Open-Source-Programm erstellen, dessen Quelle verteilt werden soll, funktioniert das Pragma möglicherweise nicht. –

+5

Es geht nicht nur um Compilerunterstützung, sondern auch darum, wie kompliziert die Umgebung ist. Vertrauen Sie dem Compiler, * sicher * zu wissen, ob zwei Dateien gleich sind oder nicht, einschließlich aller mount-Dateien und symbolischer Links? –

+2

auch Hilfswerkzeuge wie Indexer und Analysatoren berücksichtigen. Möglicherweise ist kein vollständiger Präprozessor oder Parser dahinter, wie es für den Compiler der Fall ist. – justin

Antwort

13

Es hängt davon ab, wie viel portable Ihr Programm zu erwarten ist.

Solange Sie ein Programm schreiben, das mit Compilern arbeiten soll, von denen Sie sicher wissen, dass sie #prama once unterstützen, sollte nur die Verwendung von #pragma once ausreichen. Wenn Sie dies tun, beschränken Sie Ihr Programm auf Compiler, die das implementierungsdefinierte Feature unterstützen.

Wenn Sie Ihr Programm benötigen, um auf alle Compiler zu arbeiten, dann sollten Sie #pragma once verwenden und Wachen beide enthalten.

Falls ein Compiler nicht #pragma once es einfach ignorieren unterstützt wird es [Ref # 1], in einem solchen Fall die Kopf Wachen Sie den Zweck dienen, also nichts falsch in ihnen mit beiden, wenn Sie nicht bewusst sind, von Features, die von Ihren Zielcompilern unterstützt werden.

Wenn Sie also möchten, dass Ihr Programm zu 100% portabel auf verschiedenen Compilern ist, ist der ideale Weg, nur die Include-Wächter zu verwenden. Wie @CharlesBailey zu Recht darauf hinweist, da das Verhalten für #pragma once Implementierung definiert ist, kann sich das Verhalten auf einem unbekannten Compiler nachteilig auf Ihr Programm auswirken.


[Ref # 1]
Standard C++ 03: 16,6 Pragma Direktive

Eine Präprozessordirektive des Formulars

# pragma pp-tokensopt new-line

bewirkt, dass die Implementierung, um sich in einer implementierungsdefinierten Weise zu verhalten. Jedes Pragma, das von der Implementierung nicht erkannt wird, wird ignoriert.

+7

Wenn Sie möchten, dass Ihr Programm 100.00% portabel ist, müssen Sie Wächter verwenden, aber Sie müssen auch vermeiden, '#pragma once' zu ​​verwenden, da das implementierungsdefinierte Verhalten aktiviert ist Ein unbekannter Compiler könnte sich nachteilig auf Ihr Programm auswirken. –

+0

@CharlesBailey: Einverstanden. Die Antwort muss geändert werden. Ich werde das tun.Vielen Dank. –

+3

'#pragma once' wird fehlschlagen, wenn die gleiche Datei auf Betriebssystem-/Dateisystemebene mit zwei verschiedenen Aliasnamen versehen ist. Ein # include-guard in der Datei hat jedoch unabhängig von der Dateisystemreferenz den gleichen Namen und funktioniert weiterhin. – abelenky

10

Es ist nicht-Standard so, wenn Sie einen sicheren Gebrauch sein wollen, dass die Wachen sind

5

Wie Ihre Tabelle zeigt es sehr selten ist jetzt einen Compiler in Mainstream-Nutzung zu begegnen, die nicht #pragma once unterstützt. Um eine Codebasis sauber und kostengünstig in der Wartung zu halten, ist ein ständiger Refactoring-Aufwand erforderlich. Jedes Mal, wenn Sie eine Klasse umbenennen oder einen Code verschieben, müssen die Wächter jedesmal aktualisiert werden, um diese Aufgabe erheblich zu erhöhen.

Also würde ich sagen, abgesehen von einigen Nischen-Ecke Fällen oder für defekte Build-Systeme #pragma once ist in der Praxis sicher zu verlassen. Wenn Sie sich für Produktivität und Code-Qualität mit nur #pragma once interessieren, scheint die offensichtliche Wahl.

Die Ausnahmen sind, wenn Sie eine Bibliothek schreiben, die jeden Compiler unter der Sonne unterstützen muss oder Pech haben, mit einem dieser seltenen Compiler arbeiten zu müssen, die diese Funktion nicht haben.