Frage

Ich habe eine Reihe von Legacy-Code, die ich für Unit-Tests schreiben müssen. Es verwendet vorkompilierte Header überall so fast alle CPP-Dateien einen dependecy auf stdafx.h haben, die es schwer zu brechen Abhängigkeiten, um Tests zu schreiben macht.

Mein erster Instinkt ist, alle diese stdafx.h Dateien zum größten Teil, die zu entfernen, # include-Direktiven enthalten und diese #includes direkt in den Quelldateien legen je nach Bedarf.

Dies würde es erforderlich machen, vorkompilierte Header zu deaktivieren, da sie auf mit einer Datei wie stdafx.h abhängig sind, um zu bestimmen, wo die vorkompilierte Header stoppen.

Gibt es eine Möglichkeit vorkompilierte Header ohne die stdafx.h Abhängigkeiten zu halten? Gibt es einen besseren Weg, um dieses Problem zu nähern?

War es hilfreich?

Lösung

Ja, es gibt einen besseren Weg.

Das Problem, IMHO, mit dem ‚Assistenten-Stil‘ des vorkompilierte Header ist, dass sie nicht benötigte Kopplung fördern und machen Wiederverwendung von Code schwieriger, als es sein sollte. Auch Code, den Stil mit dem ‚in stdafx.h einfach alles bleiben‘ geschrieben worden ist, ist anfällig für einen Schmerz zu sein, wie etwas zu ändern in jeder Header-Datei zu erhalten ist wahrscheinlich die gesamte Code-Basis verursachen jedes Mal neu zu kompilieren. Dies kann einfach Refactoring macht ewig dauern, da jede Veränderung und neu kompilieren Zyklus dauert viel länger, als es sollte.

Eine bessere Möglichkeit, wieder IMHO ist #pragma hdrstop und / Yc und / Yu zu verwenden. Dies ermöglicht Ihnen eine einfache Build-Konfigurationen einrichten, um die vorkompilierte Header DO verwenden und auch Konfigurationen bauen, die keine vorkompilierte Header verwenden. Die Dateien, die vorkompilierte Header verwenden Sie haben keine direkte Abhängigkeit von dem vorkompilierte Header selbst in der Quelldatei, die sie mit oder ohne vorkompilierte Header sein ermöglicht zu bauen. Die Projektdatei legt fest, welche Quelldatei den vorkompilierte Header und die Pragma hdrstop Linie in jeder Quelldatei erstellt wird bestimmt, welche von dem vorkompilierte Header entnommen enthält (falls verwendet) und die direkt aus der Quelldatei genommen werden ... Das bedeutet, dass, wenn tun Wartung würden Sie die Konfiguration verwenden, die nicht vorkompilierte Header nicht verwendet und nur den Code, den Sie brauchen, um wieder aufzubauen, nachdem eine Header-Datei Änderung wieder aufbauen wird. Wenn voll zu tun baut können Sie die vorkompilierte Header-Konfigurationen verwenden, den Übersetzungsvorgang zu beschleunigen. Eine weitere gute Sache über die Nicht-vorkompilierte Header Build-Option ist, dass es dafür sorgt, dass Ihre CPP-Dateien nur enthalten, was sie brauchen und umfassen alles, was sie brauchen (etwas, das schwer ist, wenn man den ‚Assistenten-Stil‘ des vorkompilierte Header verwenden.

Ich habe ein bisschen darüber geschrieben, wie das funktioniert hier: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop. html (das Zeug über / FI ignorieren) und ich einige Beispielprojekte, die hier mit dem pragma hdrstop und / YC / Yu Methode bauen: http://www.lenholgate.com/blog/2008/04/practical-testing-16 --- Befestigungs-a-Timeout-bug.html .

Natürlich aus dem ‚Assistenten-Stil‘ bekommt vorkompilierte Header Nutzung zu einem kontrollierteren Stil ist oft nicht trivial ...

Andere Tipps

Wenn Sie normalerweise vorkompilierte Header verwenden „stdafx.h“ dient 2 Zwecken. Es definiert eine Reihe von stabilen, gemeinsamen Include-Dateien. Auch in jeder CPP-Datei, es dient als Marker, wie, wo die vorkompilierte Header beenden.

Klingt wie, was Sie tun möchten, ist:

  • Lassen Sie vorkompilierte Header aktiviert.
  • Lassen Sie den „stdafx.h“ sind in jeder CPP-Datei.
  • schüttet das schließt aus „stdafx.h“.
  • Für jede CPP-Datei, herauszufinden, welche von der alten „stdafx.h“ benötigt wurden, umfasst. Fügen Sie diese vor dem # include „stdafx.h“ in jeder CPP-Datei.

So, jetzt haben Sie die minimale Menge von Abhängigkeiten, und Sie haben noch vorkompilierte Header verwenden. Der Verlust ist, dass Sie nicht Ihren gemeinsamen Satz von Header Vorkompilieren nur einmal. Dies wäre ein großer Erfolg für ein voll wieder aufzubauen. Für die Entwicklung Modus, in dem Sie nur ein paar Dateien zu einem Zeitpunkt neu zu kompilieren, würde es weniger ein Hit werden.

Nein, es gibt wahrscheinlich nicht einen besseren Weg.

Doch für eine bestimmte Person CPP-Datei, können Sie entscheiden, dass Sie die vorkompilierte Header nicht benötigen. Sie könnten die Einstellungen für diese eine CPP-Datei ändern und die stdafx.h Zeile entfernen.

(Eigentlich aber ich weiß nicht, wie das vorkompilierte Header-Schema wird mit dem Schreiben von Komponententests interferring).

Nein. vorkompilierte Header beruht auf einem einzigen Header von allen Quellen auf diese Weise zusammengestellt enthalten. Sie für eine einzelne Quelle angeben können nicht (oder alle) an allen vorkompilierte Header zu verwenden, aber das ist nicht das, was Sie wollen.

In der Vergangenheit Borland C ++ Compiler hat Vorkompilierung ohne einen bestimmten Header. Wenn jedoch zwei Quellen Dateien die gleichen Header enthalten, aber bei verschiedenen , um , wurden sie separat kompiliert, da zwar die Reihenfolge der Header-Dateien in C ++ kann Materie ...

So bedeutet es, dass der borland vorkompilierte Header gespeichert hat Zeit nur, wenn Sie sehr starr Quellen in der gleichen Reihenfolge enthalten, oder hatten ein einzelne Include-Datei enthielt (ersten) von allen anderen Dateien ... - klingt vertraut? ?!

Ja. Der "stdafx.h / stdafx.pch" Name ist nur Konvention. Sie können jeder geben, ihren eigenen vorkompilierte Header .cpp. Dies würde wahrscheinlich am einfachsten durch ein kleines Skript zu erreichen, um die XML in Ihren VCPROJ zu bearbeiten. Nachteil:. Sie mit einem großen Stapel von vorkompilierte Header am Ende, und sie sind nicht zwischen TU geteilt

Möglich, aber klug? Ich kann nicht sicher sagen.

Mein Rat ist - nicht entfernen vorkompilierte Header, wenn Sie möchten, dass Ihre baut quälend langsam machen. Sie haben grundsätzlich drei Möglichkeiten:

  1. Werden Sie vorkompilierte Header befreien (nicht empfohlen)
  2. Erstellen Sie eine separate Bibliothek für den Legacy-Code; Auf diese Weise können sie separat bauen.
  3. Verwenden Sie mehrere vorkompilierte Header innerhalb eines einzigen Projekts. Sie können einzelne C ++ Dateien in Ihrem Solution Explorer auswählen und sie sagen, welche Header precomiled zu verwenden. Sie müssen auch Ihre OtherStdAfx.h / CPP-Setup eine vorkompilierte Header zu erzeugen.

vorkompilierte Header wird auf der Idee ausgesagt, dass alles den gleichen Satz von Sachen enthalten. Wenn Sie von vorkompilierte Header machen wollen, dann müssen Sie mit den Abhängigkeiten leben, dass dies impliziert. Es kommt zu einem Kompromiss der Abhängigkeiten vs der Baugeschwindigkeit nach unten. Wenn Sie in einer angemessenen Zeit mit dem vorkompilierte Header ausgeschaltet dann bauen können mit allen Mitteln tun.

Eine andere Sache zu prüfen ist, dass Sie eine pch pro Bibliothek haben. So können Sie in der Lage sein, Ihren Code in kleinere Bibliotheken aufgeteilt und haben jede von ihnen einen engeren Satz von Abhängigkeiten.

Ich verwende nur vorkompilierte Header für den Code, der die afx___ Sachen umfassen muss - in der Regel nur UI, die ich nicht Unit-Test zu tun. UI-Code behandelt UI und ruft Funktionen, die Komponententests tun haben (obwohl die meisten nicht zur Zeit aufgrund der App sein Vermächtnis).

Für den Großteil des Codes ich vorkompilierte Header nicht verwenden.

G.

vorkompilierte Header können viel Zeit sparen, wenn ein Projekt zum Umbau, aber wenn eine vorkompilierte Header ändert, alle Quelldatei auf dem Header je neu kompiliert werden, ob die Änderung betrifft oder nicht. Glücklicherweise sind vorkompilierte Header verwendet, um Compile nicht link ; jede Quelldatei nicht den zu ihrer Verwendung vorkompilierte Header.

pch1.h:

#include <bigHeader1.h>
#include ...


pch1.cpp:

#include "pch1.h"


source1.cpp:

#include "pch1.h"
[code]


pch2.h:

#include <bigHeader2.h>
#include ...


pch2.cpp:

#include "pch2.h"


source2.cpp

#include "pch2.h"
[code]

Wählen Sie pch1.cpp , rechts klicken, Eigenschaften, Konfigurationseigenschaften, C / C ++, vorkompilierte Header .
Precompiled Rubrik: Create (/ YC)
vorkompilierte Header-Datei: pch1.h
vorkompilierte Header-Ausgabedatei : $ (INTDIR) pch1.pch

Wählen Sie source1.cpp
Precompiled Rubrik: Verwenden (/ Yu)
vorkompilierte Header-Datei: pch1.h
vorkompilierte Header-Ausgabedatei : $ (INTDIR) pch1.pch (ich glaube nicht, das wichtig ist für / Yu)

Machen Sie dasselbe für pch2.cpp und source2.cpp , mit der Ausnahme stellen Sie die Header-Datei und Rubrik Ausgabedatei pch2.h und pch2.pch . Das funktioniert für mich.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top