443 Stimmen

Ist #pragma einmal ein sicherer Include-Schutz?

Ich habe gelesen, dass es eine Compiler-Optimierung gibt, wenn man #pragma once was zu einer schnelleren Kompilierung führen kann. Ich weiß, dass dies nicht dem Standard entspricht und daher ein Problem mit der plattformübergreifenden Kompatibilität darstellen könnte.

Ist dies etwas, das von den meisten modernen Compilern auf Nicht-Windows-Plattformen (gcc) unterstützt wird?

Ich möchte Probleme bei der Kompilierung von Plattformen vermeiden, aber auch die zusätzliche Arbeit von Fallback-Guards vermeiden:

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

Sollte ich mir Sorgen machen? Sollte ich weitere geistige Energie darauf verwenden?

3voto

CMircea Punkte 3515

Heute sind Include-Guards der alten Schule so schnell wie ein #pragma once. Selbst wenn der Compiler sie nicht besonders behandelt, bleibt er stehen, wenn er sieht, dass #ifndef WHATEVER und WHATEVER definiert ist. Das Öffnen einer Datei ist heute spottbillig. Selbst wenn es eine Verbesserung gäbe, läge sie in der Größenordnung von Millisekunden.

Ich verwende #pragma einfach nicht, da es keinen Nutzen hat. Um Kollisionen mit anderen Include-Guards zu vermeiden, verwende ich etwas wie: CI_APP_MODULE_FILE_H --> CI = Firmeninitialen; APP = Anwendungsname; der Rest ist selbsterklärend.

3voto

raidsan Punkte 761

Wenn wir msvc oder Qt (bis zu Qt 4.5) verwenden, da GCC (bis zu 3.4) und msvc beide unterstützen #pragma once kann ich keinen Grund erkennen, der gegen die Verwendung von #pragma once .

Der Name der Quelldatei entspricht normalerweise dem Klassennamen, und wir wissen, dass wir manchmal Refactor um den Klassennamen umzubenennen, dann mussten wir die #include XXXX auch, so dass ich denke, Handbuch pflegen die #include xxxxx Auch mit der Visual Assist X-Erweiterung ist die Beibehaltung von "xxxx" keine notwendige Arbeit.

3voto

Marcel Punkte 127

Ein zusätzlicher Hinweis an die Leute, die meinen, dass eine automatische, einmalige Einbindung von Header-Dateien immer gewünscht ist: Ich baue seit Jahrzehnten Codegeneratoren mit doppelter oder mehrfacher Einbindung von Headerdateien. Besonders für die Generierung von Protokollbibliotheks-Stubs finde ich es sehr angenehm, einen extrem portablen und leistungsfähigen Codegenerator ohne zusätzliche Werkzeuge und Sprachen zu haben. Ich bin nicht der einzige Entwickler, der dieses Schema verwendet, denn dieser Blog X-Macros zeigen. Dies wäre ohne die fehlende automatische Bewachung nicht möglich.

2voto

Tim Post Punkte 32750

Die Verwendung von gcc 3.4 und 4.1 auf sehr großen Bäumen (manchmal unter Verwendung von distcc ), habe ich noch keine Geschwindigkeitssteigerung feststellen können, wenn ich #pragma einmal anstelle von oder in Kombination mit Standard-Include-Guards verwende.

Ich sehe wirklich nicht, wie es sich lohnt, ältere Versionen von gcc oder sogar anderen Compilern zu verwirren, da es keine wirklichen Einsparungen gibt. Ich habe nicht versucht, alle der verschiedenen de-Lintern, aber ich bin bereit zu wetten, es wird viele von ihnen verwirren.

Auch ich hätte mir gewünscht, dass es schon früh eingeführt worden wäre, aber ich kann das Argument "Warum brauchen wir das, wenn ifndef perfekt funktioniert?" verstehen. In Anbetracht der vielen dunklen Ecken und Komplexitäten von C sind Include Guards eine der einfachsten, selbsterklärenden Dinge. Wenn man auch nur ein wenig weiß, wie der Präprozessor funktioniert, sollten sie selbsterklärend sein.

Wenn Sie jedoch eine deutliche Beschleunigung feststellen, aktualisieren Sie bitte Ihre Frage.

1voto

Shammi Punkte 492

Der Hauptunterschied besteht darin, dass der Compiler die Header-Datei öffnen musste, um den Include Guard zu lesen. Im Vergleich dazu führt pragma once dazu, dass der Compiler die Datei im Auge behält und kein File IO durchführt, wenn er auf ein anderes Include für dieselbe Datei stößt. Das mag zwar vernachlässigbar klingen, kann aber bei großen Projekten, insbesondere bei solchen ohne gute Header-Include-Disziplinen, leicht ins Gewicht fallen.

Das heißt, in diesen Tagen Compiler (einschließlich GCC) sind intelligent genug, um Include-Guards wie pragma einmal zu behandeln. d.h. sie nicht öffnen die Datei und vermeiden die Datei IO Strafe.

In Compilern, die pragma nicht unterstützen, habe ich manuelle Implementierungen gesehen, die ein wenig umständlich sind.

#ifdef FOO_H
#include "foo.h"
#endif

Ich persönlich mag den #pragma once Ansatz, da er den Ärger mit Namenskollisionen und möglichen Tippfehlern vermeidet. Es ist auch eleganter Code im Vergleich. Das heißt, für portablen Code, sollte es nicht schaden, beide zu haben, es sei denn, der Compiler beschwert sich über sie.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X