Warum wird die Vorwärtsdeklaration von Google Style Guide abgelehnt?

8

Nicht zu sagen, dass der Google Style Guide die heilige Bibel ist, aber als Anfänger-Programmierer scheint das eine gute Referenz zu sein.

Im Google Style Guide sind die folgenden Nachteile der Vorwärtsdeklaration aufgeführt:

  1. Vorwärtsdeklarationen können eine Abhängigkeit verbergen, sodass Benutzercode die notwendige Neukompilierung überspringen kann, wenn sich die Header ändern.

  2. Eine Vorwärtsdeklaration kann durch nachfolgende Änderungen an der Bibliothek unterbrochen werden. Vorwärtsdeklarationen von Funktionen und Vorlagen können verhindern, dass Headereigentümer anderweitig kompatible Änderungen an ihren APIs vornehmen, z. B. einen Parametertyp erweitern, einen Vorlagenparameter mit einem Standardwert hinzufügen oder in einen neuen Namespace migrieren.

  3. Vorwärts Deklaration von Symbolen aus Namespace std :: liefert undefiniertes Verhalten.

  4. Es kann schwierig sein festzustellen, ob eine Vorwärtsdeklaration oder ein vollständiges #Include benötigt wird. Das Ersetzen eines # include mit einer forward-Deklaration kann die Bedeutung des Codes stillschweigend ändern:

Code:

%Vor%

Wenn #include durch forward decls für B und D ersetzt wurde, würde test () f (void *) aufrufen.

  1. Das Weitergeben mehrerer Symbole aus einer Kopfzeile kann ausführlicher sein als einfach # das Hinzufügen der Kopfzeile.

  2. Strukturierungscode zum Aktivieren von Vorwärtsdeklarationen (z. B. Verwenden von Zeigerelementen anstelle von Objektelementen) kann den Code langsamer und komplexer machen.

Eine Suche nach SO scheint jedoch darauf hinzudeuten, dass eine Vorwärtsdeklaration allgemein eine bessere Lösung ist.

Kann angesichts dieser scheinbar nicht-trivialen Nachteile jemand diese Diskrepanz erklären?

Und wann ist es sicher, einige oder alle dieser Nachteile zu ignorieren?

    
Woofas 13.04.2016, 11:24
quelle

2 Antworten

6
  

Einige Suche nach SO schien darauf hinzuweisen, dass die Vorwärtsdeklaration ist   universell eine bessere Lösung.

Ich glaube nicht, dass SO das sagt. Der Text, den Sie angeben, vergleicht eine "Guerilla" -Forward-Deklaration mit der Aufnahme der richtigen Include-Datei. Ich denke nicht, dass Sie bei der Vorgehensweise, die Google hier kritisiert, viel Unterstützung finden. Dieser schlechte Ansatz ist, "Nein, nicht #include Include-Dateien, schreiben Sie einfach Deklarationen für die wenigen Funktionen und Typen, die Sie verwenden möchten."

Die richtige Include-Datei enthält noch eigene Vorwärtsdeklarationen, und eine Suche nach SO wird vorschlagen, dass dies das Richtige ist, also sehe ich, wo Sie die Idee haben, dass SO für Deklarationen ist. Aber Google sagt nicht, dass die Include-Datei einer Bibliothek keine Forward-Deklarationen enthalten sollte, sondern dass Sie nicht schurkisch werden und Ihre eigene Forward-Deklaration für jede Funktion oder jeden Typ schreiben sollten, die Sie verwenden möchten.

Wenn Sie #include die richtige Include-Datei verwenden und Ihre Build-Kette funktioniert, dann ist die Abhängigkeit nicht verborgen und der Rest der Probleme meist trifft nicht zu, obwohl die Include-Datei enthält Deklarationen. Es gibt immer noch einige Schwierigkeiten, aber darüber redet Google hier nicht.

Wenn man insbesondere auf Vorwärtsdeklarationen von Typen im Vergleich zu Klassendefinitionen für sie schaut, (4) gibt dies ein Beispiel dafür, dass es schief geht (da eine Forward-Deklaration von D nicht ausdrücken kann, dass sie von B abgeleitet ist) Sie benötigen die Klassendefinition). Es gibt auch eine Technik namens "Pimpl", die vorsichtige Verwendung einer Deklaration vom Typ forward für einen bestimmten Zweck macht. Also wird es wieder Unterstützung auf SO geben, aber das ist nicht das Gleiche wie die Idee zu unterstützen, dass jeder im Allgemeinen um vorwärts deklarierende Klassen herumlaufen sollte anstatt von #include in der Kopfzeile Dateien.

    
Steve Jessop 13.04.2016, 11:39
quelle
3

Von Titus Winters CppCon 2014 Diskussion :

  

Der große Punkt, den wir in letzter Zeit gelernt haben, ist: Forward, der etwas mit einer Vorlage deklariert, ist eine wirklich schlechte Idee. Dies führte zu Wartungsproblemen, wie Sie es nicht glauben würden. Vorwärtsdeklaration kann in Ordnung sein, in einigen Fällen? Mein Verdacht ist, dass sich die Regel tatsächlich ändert: Bibliothekseigentümer werden ermutigt, einen Header bereitzustellen, der speziell die Dinge, die sie für wert halten, erklärt (Hervorhebung hinzugefügt), und Sie sollten es wahrscheinlich nicht tun Forward deklarieren Sie sich selbst, und niemand sollte jemals einen Template-Typ deklarieren. Wir werden sehen. Wir arbeiten immer noch an den [unhörbaren] Details aus dem, was wir gelernt haben.

Vielleicht könnten Probleme mit dem Versuch, deklarierte Templates direkt zu deklarieren, eines ihrer Motive sein, um Forward Declaration Wholesale zu entmutigen ...?

Auch die Angabe "eines Headers, der spezifisch vorwärts führt, erklärt die Dinge, von denen er denkt, dass sie es wert sind" klingt ähnlich wie <iosfwd> , wie beschrieben hier (Lösung 2.2), hier und hier .

BEARBEITEN:

Um es klar zu sagen, ich habe nicht gesagt, dass ich der Ablehnung der Vorwärtsdeklaration von Google zustimme oder nicht zustimme. Ich habe nur versucht, ihre Gründe zu verstehen, und machte eine Seite / Beobachtung über <iosfwd> .

Persönlich verwende ich Vorwärts-Deklarationen, wann immer ich kann, und befolge die Richtlinie, die später in demselben GOTW oben verlinkt (Lösung 3):

  

Richtlinie: Nie #include eine Überschrift, wenn eine Vorwärtsdeklaration ausreicht.

aber Winters Argumentation scheint auch einige Vorteile zu haben. Ich habe an Code gearbeitet, bei dem ich Template-Typen aus einer Third-Party-Library weiterleitete, und die Syntax wird unordentlich (ich habe noch nicht auf die Wartungsprobleme hingewiesen, auf die Winters hingewiesen hat). OTOH, ich bin mir nicht sicher, ob ich alle Vorwärtsdeklarationen wie im Google C ++ - Stilleitfaden angegeben abwehren sollte, aber ich denke, das funktioniert bei Google?

Disclaimer: Ich bin kein Experte, lerne immer noch.

    
Quokka 26.11.2016 08:24
quelle