2009-08-10 11 views
5

Ich nehme an, die meisten C++ - Compiler werden in Assembly geschrieben. Was sie zu verschiedenen Sprachen macht (ich könnte falsch liegen). Wenn ich eine cout Style-Funktion für einfaches altes C erstellen würde, wie würde ich das machen? cout hat einige sehr beeindruckenden Features zum Beispiel dieser Schnipsel nehmen:Erstellen einer Cout-Funktion in C?

// endl not only prints a new line but also flushes the stream 
cout << "Hello World!" << endl; 

Was ich bin mir ziemlich sicher, dass in C dies übersetzt:

printf("Hello World!\n"); 
fflush(1);     //stdout = 1 

nächsten Auftrag des Geschäfts, die << Betreiber. In C++ wäre das einfach (Überladen des Operators), aber ich kann mir keinen einzigen Weg vorstellen, dies in C zu tun.

+2

Nicht sicher implementieren könnte, wo auf diesem starten ... Die kurze Antwort ist, dass die C++ Sprache ist so definiert, dass eine Syntax wie diese möglich ist, und die C-Sprache nicht. - Aber Ihre Frage könnte aus dem "Wie schreibe ich einen Compiler für eine C-Erweiterung Sprache?" den ganzen Weg bis "Wie kann ich Iostream-Funktionalität in einer benutzerdefinierten Bibliothek mit C-Stil-Makros für spezielle Syntax duplizieren?" –

+0

@Conspicuous Compiler: Ich weiß was du sagst. Deshalb habe ich es als hypothetisch bezeichnet. Es ist nicht wichtig ... Ich bin nur neugierig. – Kredns

+4

Die meisten C++ - Compiler sind in C oder C++ geschrieben - und nicht in Assembly. –

Antwort

5

Das ist richtig, weil C keine Überlastung des Operators hat, können Sie das Verhalten des < nicht ändern < Operator, es wird immer eine Bitverschiebung, so gibt es keine Möglichkeit, 'Cout' mit der genauen Semantik in C++ zu schreiben, in C.

Aus Interesse, g ++ (GNU C++ Compiler) wird meistens geschrieben in C.

4

C ist eigentlich eine beliebte Implementierungssprache für C++ - Compiler und Standardbibliotheken (so ist C++ selbst, ein Konzept manchmal auch als Self-Hosting oder Bootstrapping einer Sprache bekannt), und Sie können studiere die ganzen Quellen einer reichen, komplexen C++ - Standardbibliothek (plus Erweiterungen) here (Entschuldigung, das ist gcc 3 - kann keinen gcc 4-Quellbaum finden, der genauso einfach online durchsucht werden kann, aber natürlich kannst du ihn einfach herunterladen Quellen und studieren sie auf Ihrem lokalen Rechner). Ich würde vorschlagen, stattdessen mit einem guten Buch zu beginnen, wie zB this one - die Quellen werden für Sie viel aussagekräftiger sein, sobald Sie alle dunklen Ecken und Kanten von C++ 's Iostreams (wie ein Bonus, das Buch nimmt Sie auch mit auf eine Führung durch Orte - halten Sie sich an Ihren Hut! -).

8

Es kann helfen, darüber nachzudenken, zwischen der "< <" Operatorsyntax und der "Operator < <" Funktionssyntax zu übersetzen. Ihr C++ Beispiel entspricht dieses Bit von C++ Code:

operator<< (operator<< (cout, "Hello World!"), endl); 

Das erste, was Sie hier bemerken sollen, ist, dass es eigentlich nicht viel Klugheit überhaupt in cout. Was schlau ist, ist der Operator < < Funktion - speziell die Version des Operators < < Funktion, die ein Stream-Objekt als erstes Argument nimmt (was cout ist, aber auch viele andere Dinge). Oder, noch genauer, der Bereich des Operators < < Funktionen, die ein Stream-Objekt als erstes Argument nehmen, und eine bestimmte Sache als zweites Argument nehmen - es gibt einen für jeden Objekttyp, den Sie in den Cout-Stream einfügen können. Sie können einen der C++ - Tricks auch in dieser Syntax sehen; der Operator < < Funktionen an Stream-Objekten geben immer das Stream-Objekt zurück, das ihnen gegeben wurde, wodurch eine Verkettung dieser Art ermöglicht wird.

Um C++ - Code in Linker und System-ABIs zu setzen, die C-ähnliche Funktionssyntax erwarten, "zerlegen" die meisten C++ - Compiler die Funktionsnamen, um in ihnen den Typ der Argumente zu codieren, die sie haben. (Außerdem ist der "< <" kein gültiger C-ähnlicher Funktionsname.) Wenn Sie sich also die generierte Assembly für dieses Funktions-Bit angesehen haben, würden Sie sehen, dass die Namen der beiden Funktionen lauten voneinander verschieden - sie hätten Suffixe, die die Argumenttypen anzeigen.Man könnte so etwas wie das manuell tun:

operator_lshift__stream__endl(
    operator_lshift__stream__string(cout, "Hello World!"), endl); 

Und da haben Sie etwas bekam, die Sie in C.