Warum unterscheiden sich C und C ++ auch nach der Kompilierung?

7
Ich habe es erraten, war aber immer noch überrascht zu sehen, dass die Ausgabe dieser beiden in C und C ++ geschriebenen Programme, wenn sie kompiliert wurden, sehr unterschiedlich waren. Das lässt mich denken, dass das Konzept der Objekte immer noch auf der untersten Ebene existiert. Ist das ein zusätzlicher Aufwand? Wenn ja, ist es derzeit eine unmögliche Optimierung objektorientierter Code in prozeduralen Stil zu konvertieren oder nur sehr schwer zu tun?

helloworld.c

%Vor%

helloworld.cpp

%Vor%

Kompiliert wie folgt:

%Vor%

Erzeugt diesen Code:

C-Baugruppe

%Vor%

C ++ Assembly

%Vor%     
ArturPhilibin 18.02.2011, 02:16
quelle

5 Antworten

19

Unterschiedliche Compiler erzeugen unterschiedlichen Code. Eine frühe Version von gcc im Vergleich zur aktuellen Version von gcc erzeugt wahrscheinlich anderen Code.

Noch wichtiger ist, dass iostream eine Menge Dinge erledigt, stdio nicht, so dass es offensichtlich einige erhebliche Gemeinkosten geben wird. Ich verstehe, dass diese theoretisch in einen identischen Code kompiliert werden könnten, aber was sie tun, ist technisch nicht identisch.

    
Jamie Wong 18.02.2011, 02:19
quelle
8

Hier geht es nicht um Objekte oder Optimierung: printf und cout sind grundsätzlich sehr unterschiedliche Bestien. Für einen faireren Vergleich ersetzen Sie Ihre cout -Anweisung im C ++ Code durch printf . Die Optimierung ist ein Problem, wenn Sie auf stdout ausgeben, da der Flaschenhals sicherlich der Puffer des Terminals ist.

    
Seth Johnson 18.02.2011 02:20
quelle
6

Sie rufen nicht die gleichen Funktionen im C ++ - Beispiel wie das C-Beispiel auf. Ersetzen Sie die std :: cout-Pipes genauso wie den C-Code durch einen einfachen alten printf, und Sie sollten eine viel größere Korrelation zwischen der Ausgabe der beiden Compiler sehen.

    
dthorpe 18.02.2011 02:23
quelle
2

Sie müssen feststellen, dass es in C ++ eine ganze Menge "anderer" Dinge gibt. Globale Konstruktoren zum Beispiel. Auch die Bibliotheken sind anders.

Das C ++ - Stream-Objekt ist viel komplizierter als C io, und wenn Sie den Assembler durchsehen, können Sie den gesamten Code für Pthreads in der C ++ - Version sehen.

Es ist nicht unbedingt langsamer, aber es ist sicherlich anders.

    
Brian Makin 18.02.2011 02:21
quelle
2
  

Ich habe es erraten, war aber immer noch überrascht zu sehen, dass die Ausgabe dieser beiden Programme, geschrieben in C und C ++, bei der Kompilierung sehr unterschiedlich war.

Ich bin überrascht, dass Sie überrascht waren - es sind völlig verschiedene Programme.

  

Das lässt mich denken, dass das Konzept der Objekte immer noch auf der untersten Ebene existiert.

Absolut ... Objekte sind die Art wie der Speicher während der Programmausführung angelegt und verwendet wird (vorbehaltlich Optimierungen).

  

Erhöht dies den Overhead?

Nicht unbedingt oder typisch - die gleichen Daten müssten irgendwo liegen, wenn die Arbeit auf die gleiche logische Art koordiniert würde.

  

Wenn ja, ist es derzeit eine unmögliche Optimierung objektorientierter Code in prozeduralen Stil zu konvertieren oder nur sehr schwer zu tun?

Das Problem hat nichts mit OO oder prozeduralem Code zu tun, oder einer ist effizienter als der andere. Das Hauptproblem, das Sie hier beobachten, ist, dass die Ostreams von C ++ etwas mehr Setup und Abbau erfordern und mehr von der I / O durch Inline-Code koordiniert werden, während printf () mehr Out-of-Line in der vorkompilierten Bibliothek hat kann es in Ihrem kleinen Code-Listing nicht sehen. Es ist nicht klar, was wirklich "besser" ist, und es sei denn, Sie haben ein Leistungsproblem, das das Profiling zeigt, sollten Sie es vergessen und einige nützliche Programmierung getan haben.

BEARBEITEN als Antwort auf einen Kommentar:

Fairer Anruf - war ein bisschen hart formuliert - Entschuldigung. Es ist eine schwierige Unterscheidung, um tatsächlich zu machen ... "nur der Compiler [weiß] von Objekten" ist in einem Sinne wahr - sie sind keine eingekapselten, halb heiligen, diskreten "Dinge" für den Compiler, wie sie für den Programmierer sein können . Und wir könnten ein Objekt schreiben, das genau so verwendet werden kann, wie Sie cout verwendet haben, das während der Kompilierung verschwinden würde und einen Code erzeugen würde, der der printf () - Version entspricht. Aber, cout und iostreams beinhalten etwas Setup, weil es threadsicher und mehr inline ist und verschiedene Locales behandelt, und es ist ein echtes Objekt mit Speicheranforderungen, da es mehr unabhängige Informationen über den Fehlerstatus enthält, ob Ausnahmen ausgelöst werden sollen -file-Bedingungen (printf () betrifft "errno", was dann vom nächsten Bibliotheks- / OS-Aufruf geplättert wird) ....

Was Sie aufschlussreicher finden könnten, ist zu vergleichen, wie viel zusätzlicher Code generiert wird, wenn Sie einen weiteren String drucken, da die Menge an Code im Wesentlichen konstanter Overhead + ein gewisser Betrag pro Nutzung ist und in letzterer Hinsicht ostream - Basierter Code kann je nach den angeforderten Typen und Formatierungen genauso effizient sein wie printf (). Es ist auch erwähnenswert, dass ...

%Vor%

... ist korrekt und entspricht Ihrer printf () -Anweisung ... std::endl fordert explizit eine unnötige Flush-Operation an, da ein standardkonformes C ++ - Programm seine Puffer spült und schließt, wenn der Stream den Gültigkeitsbereich verlässt Wie auch immer (es gibt einen interessanten Post heute, wo jemand den Microsoft VisualC ++ - Compiler das nicht für sie tut! - lohnt es, im Auge zu behalten, aber schwer zu glauben).

    
Tony Delroy 18.02.2011 02:26
quelle

Tags und Links