Was ist eine "Übersetzungseinheit" in C ++?

236

Ich lese gerade das von Meyers geschriebene "Effective C ++" und bin auf den Begriff "Übersetzungseinheit" gestoßen.

Könnte mir bitte jemand eine Erklärung geben für:

1) Was genau ist das?

2) Wann sollte ich in Betracht ziehen, es beim Programmieren mit C ++ zu verwenden?

3) Wenn es nur mit C ++ zusammenhängt oder mit anderen Programmiersprachen verwendet werden kann

Ich könnte es bereits verwenden, ohne den Begriff zu kennen ....

Harry
quelle
1
2. Sie verwenden die Übersetzungseinheit bereits, wenn Sie Header-Dateien eingefügt haben. Es ist ein Begriff, der als Referenz verwendet wird und kein C ++ - Konstrukt per say
talkeDskobeDa

Antworten:

268

Von hier aus : ( Wayback Machine Link )

Gemäß Standard C ++ ( Wayback Machine Link ): Eine Übersetzungseinheit ist die Grundeinheit der Kompilierung in C ++. Es besteht aus dem Inhalt einer einzelnen Quelldatei sowie dem Inhalt aller direkt oder indirekt darin enthaltenen Header-Dateien abzüglich der Zeilen, die mit bedingten Vorverarbeitungsanweisungen ignoriert wurden.

Eine einzelne Übersetzungseinheit kann in eine Objektdatei, eine Bibliothek oder ein ausführbares Programm kompiliert werden.

Der Begriff einer Übersetzungseinheit wird am häufigsten im Kontext der One Definition Rule und der Vorlagen erwähnt.

JeffH
quelle
9
Wird der Begriff nur in C / C ++ verwendet?
DekuShrub
2
@dekuShrub in der Tat, nein. In Rust ist eine Übersetzungseinheit beispielsweise eine Kiste. In C ++ wird dasselbe als gesamte Bibliothek bezeichnet. Der Begriff selbst ist universell, aber er begann definitiv mit C.
Sahsahae
Neue Referenz, die ungefähr angibt, was diese Antwort besagt: en.wikipedia.org/wiki/Translation_unit_(programming)
Gabriel Staples
67

Eine Übersetzungseinheit ist in jeder Hinsicht eine Datei (.c / .cpp), nachdem sie alle Header-Dateien enthält.

http://msdn.microsoft.com/en-us/library/bxss3ska%28VS.80%29.aspx

Ana Betts
quelle
3
Einschließlich Header-Dateien. Header-Dateien werden vom Compiler verarbeitet, auch wenn kein Code generiert wird. Siehe auch JeffHs Präprozessorkommentar, die Definition "alles, was der Compiler sieht" ist gut.
Marco van de Voort
10
Sie können Dateien kompilieren, die mit ".h" enden. Der Dateiname ist überhaupt nicht wichtig. Der Inhalt ist. Wenn der Inhalt von "foo.h" "int main () {}" ist, können Sie ihn kompilieren.
Johannes Schaub - litb
@LightnessRacesinOrbit: Ja, ich wollte damit sagen, dass es unorthodox ist, einen Header direkt als TU zu kompilieren, anstatt ihn indirekt über Inklusion in eine TU zu kompilieren. Der erste Kommentar wurde gelöscht, weil er einfach falsch war, und der zweite wurde beibehalten, um unseren neuen Kontext zu erhalten.
GManNickG
1
@GManNickG: Wie wäre es mit ".h-Dateien werden herkömmlicherweise nicht direkt dem Compiler zugeführt."
Leichtigkeitsrennen im Orbit
@ JohannesSchaub-litb Ich denke du meinst Link, nicht kompilieren. Sie können jede Datei kompilieren, solange es sich um C / C ++ mit allen definierten Namen handelt. Es wäre sinnlos, eine Header-Datei zu kompilieren, da der gesamte Punkt einer Header-Datei in Quelldateien aufgenommen (gelesen und kopiert) werden soll. Sie werden also bereits kompiliert, wenn Sie eine Quelldatei kompilieren, die sie enthält. Ich denke, Sie wollten damit sagen, dass Sie keine ausführbare Datei aus einer Datei erstellen können, die keine Hauptfunktion hat.
Pooya13
30

Eine schwer zu beantwortende Frage. Der C ++ - Standard besagt:

Der Programmtext wird in Einheiten gespeichert, die in dieser Internationalen Norm als Quelldateien bezeichnet werden. Eine Quelldatei wird zusammen mit allen Headern (17.4.1.2) und Quelldateien (16.2), die über die Vorverarbeitungsanweisung #include enthalten sind (16.2), abzüglich aller Quellzeilen, die von einer der Vorverarbeitungsanweisungen mit bedingtem Einschluss (16.1) übersprungen wurden, als Übersetzungseinheit bezeichnet. [Hinweis: Ein C ++ - Programm muss nicht alle gleichzeitig übersetzt werden. ]]

Für die meisten Absichten und Zwecke ist eine Übersetzungseinheit eine einzelne C ++ - Quelldatei und der Header oder andere Dateien, die sie über den Präprozessor-Mechanismus #include enthält.

Zu Ihren anderen Fragen:

2) Wann sollte ich in Betracht ziehen, es beim Programmieren mit C ++ zu verwenden?

Sie können es nicht nicht berücksichtigen - Übersetzungseinheiten sind die Basis eines C ++ - Programms.

3) Wenn es nur mit C ++ zusammenhängt oder mit anderen Programmiersprachen verwendet werden kann

Andere Sprachen haben ähnliche Konzepte, aber ihre Semantik wird sich geringfügig unterscheiden. Die meisten anderen Sprachen verwenden beispielsweise keinen Präprozessor.

Ondrej Slinták
quelle
1
Ich weiß nicht, ob das klarstellt oder nicht. Dies kann ein etwas trüber Bereich sein - aus dem von mir zitierten Standardabsatz geht nicht hervor, dass beispielsweise vorkompilierte Header zulässig sind.
1
@GMan, und hier muss man sehr vorsichtig mit der One-Definition-Regel sein. Wenn Sie eine Klasse in verschiedene Übersetzungseinheiten mit leicht unterschiedlichen Definitionen aufnehmen, bevor diese Klasse aufgenommen wird, was dazu führt, dass die Klasse unterschiedlichen Code hat, führt dies zu undefinierten Problemen.
Matt Price
6
@GMan beachten Sie die beiden vom Standard verwendeten Begriffe: "Header" und "Quelldatei". "header" wird nur für die Standardbibliothek verwendet. Eine Benutzerdatei, die in einem Code enthalten ist, wird vom Standard nicht als "Header" bezeichnet, sondern als "Quelldatei". Der Standard weiß nichts über den Unterschied zwischen ".h" und ".cpp", den wir armen C ++ - Programmierer
erfunden haben
8

Das Buch macht es klar genug. Wenn Meyers von einer "Übersetzungseinheit" spricht, meint er eine Quellcodedatei.

Ed S.
quelle
1
Wenn er über den Quellcode sprach, würde er Quelldateien sagen. Die Übersetzungseinheit wird durch Kompilieren des Quellcodes erstellt. Beachten Sie den deutlichen Unterschied. Es ist "übersetzter" Quellcode.
Dan
3
@ Dan: Nein, das ist es nicht. Eine Übersetzungseinheit eine Quellendatei enthält , die nach dem können kompiliert werden, das heißt, der Ausgang des Vorprozessors vor der Kompilierung.
Ed S.
1
Ungeachtet dessen, was der C ++ - Standard nennt, wird "Übersetzungseinheit" häufig verwendet, um die Idee einer einzelnen "Einheit" kompilierten Codes zu kommunizieren. Laut den Microsoft-Compilern verknüpfen Sie "Translation Units" direkt. msdn.microsoft.com/en-us/library/vstudio/…
Dan
1
Versuchen wir also, "C ++ - Standard" -Nazis zu sein, oder versuchen wir, den Menschen zu helfen, mit dem Rest der Branche zu kommunizieren? Ich weiß, dass dies ein C ++ - Thread ist, also gehe ich nicht auf das ein, was xcode als tu bezeichnet. Oder alle anderen Definitionen des Begriffs.
Dan
1
@ Dan: Eine Übersetzungseinheit nennt der Standard sie. Ich bin nicht wirklich besorgt über die Meinung von zufälligen Compiler-Entwicklern. Interessant, dass der Typ, der einen fast fünf Jahre alten Beitrag ausgräbt, um zu picken und mir zu sagen, dass meine Definition falsch ist, sich umdreht und mich einen "Sprachennazi" nennt, um seinen zu korrigieren. Ja, mach weiter, du bist müde damit umzugehen.
Ed S.
4

Neben dem ODR ist die Übersetzungseinheit wichtig für die Definition unbenannter Namespaces, die eine der alten Verwendungen von "statisch" ersetzt.

Ich glaube, ich habe immer noch nicht genug Punkte, um einen Kommentar unter der obersten Antwort hinzuzufügen.

Allan Stokes
quelle
3

Eine Übersetzungseinheit ist Code, der an den eigentlichen Compiler übergeben wird. Dies bedeutet normalerweise, dass die Ausgabe vom Ausführen des Präprozessors in der C-Datei erfolgt.

Sigjuice
quelle
2

C- und C ++ - Programme bestehen aus einer oder mehreren Quelldateien, von denen jede einen Teil des Programmtextes enthält. Eine Quelldatei wird zusammen mit ihren Include-Dateien (Dateien, die mit der Präprozessor-Direktive #include enthalten sind), jedoch keine Codeabschnitte enthalten, die durch Direktiven zur bedingten Kompilierung wie #if entfernt wurden, als "Übersetzungseinheit" bezeichnet.

Ganesh Murmeltier
quelle
1

Laut MSDN : C- und C ++ - Programme bestehen Programme aus einer oder mehreren Quelldateien, von denen jede einen Teil des Programmtextes enthält. Eine Quelldatei wird zusammen mit ihren Include-Dateien (Dateien, die mit der Präprozessor-Direktive #include enthalten sind), jedoch keine Codeabschnitte enthalten, die durch Direktiven zur bedingten Kompilierung wie #if entfernt wurden, als "Übersetzungseinheit" bezeichnet.

rahul
quelle
0

Jede cpp / c-Datei (Implementierungsdatei) wird in eine Übersetzungseinheit (dh eine Objektdatei (.obj)) konvertiert. Die Header in der cpp-Datei werden durch den tatsächlichen Text aus den Headerdateien ersetzt.

yesraaj
quelle
0

Wie andere gesagt haben, ist eine Übersetzungseinheit im Grunde der Inhalt einer Quelldatei nach der Vorverarbeitung. Es ist die oberste Produktion in der Sprachgrammatik; Sie müssten sich nur darum kümmern, wenn Sie einen C- oder C ++ - Compiler schreiben würden.

John Bode
quelle
1
"Sie müssten sich nur darum kümmern, wenn Sie einen C- oder C ++ - Compiler schreiben würden." Ich bin anderer Meinung: Programmierer müssen oft verstehen, was der Compiler tut. Sie müssen beispielsweise wissen, was eine Übersetzungseinheit ist, um einen wichtigen Punkt aus Punkt 5 in Effective C ++ zu verstehen: "Die relative Reihenfolge der Initialisierung nicht lokaler statischer Objekte, die in verschiedenen Übersetzungseinheiten definiert sind, ist undefiniert."
Channing Moore