Kann ein C-Compiler C++-Aufrufe erzeugen?

Herr Nilsson

Herr Nilsson

Eroberer
Da manchen Foren lange Offtopic-Diskussion zuwider sind, wollte ich [THREAD=37341]hier[/THREAD] nicht weiter diskutieren, sondern zu einem neuen Thema auch einen neuen Thread eröffnen.

Meines Wissen kann ein C-Compiler keine C++-Aufrufe erzeugen, siehe Beispiel:
Code:
$ cat call.c
int getEins(void) { return 1; }

int main(void)
{
    int eins = getEins();
}

$ gcc -c -o call_c.o call.c
$ g++ -c -o call_c++.o call.c
$ objdump -t call_c.o | grep getEins
0000000000000000 g     F .text  000000000000000b [COLOR="Red"]getEins[/COLOR]
$ objdump -t call_c++.o | grep getEins
0000000000000000 g     F .text  000000000000000b [COLOR="Red"]_Z7getEinsv[/COLOR]
Aus der Funktion int getEins(void) wurde vom C-Compiler der Aufruf getEins, vom C++-Compiler der Aufruf _Z7getEinsv generiert. Die hinzugefügten Typsignaturen sind Voraussetzung für die unter C++ erlaubte Überladung von Funktionen.

Nun hat man erkannt, daß durch dieses neue C++-Merkmal der Aufruf von Funktionen aus alten C-Bibliotheken unmöglich wird, weshalb man unter C++ den Compiler anweisen kann, Aufrufe ohne die neuen Typsignaturen aber nach dem alten C-Standard zu erzeugen, siehe [THREAD=35270]hier.[/THREAD] Hierzu mußte der C++-Standard um die sog. Linkage-Spezifikation erweitert werden[1], z.B.:
extern string-literal declaration
Als String-Literal wird standardmäßig C++ angenommen, es kann aber auch zu C gewechselt werden:
Code:
$ cat call2.cc
extern "C" int getEins(void);

int main(void)
{
    int eins = getEins();
}

int getEins(void) { return 1; }

$ [COLOR="Red"]g++[/COLOR] -c -o call2_c++.o call2.c
$ objdump -t call2_c++.o | grep getEins
0000000000000020 g     F .text  000000000000000b [COLOR="Red"]getEins[/COLOR]

Nun ist die Frage, ob es auch einen standardisierten C++-Linkage-Befehl für C gibt? Unter [2] wird zumindest ausdrücklich darauf hingewiesen:
"The linkage specification applies only to C++. It is not supported by C."

[1] Siehe Bjarne Stroustrup, Die C++-Programmiersprache, Referenz-Handbuch, Kapitel R.7.4.
[2] C/C++: Programmer's Reference, Herbert Schildt, Osborne McGraw-Hill, Unterpunkt "LINKAGE SPECIFICATION".
 
Zuletzt bearbeitet:
Also, kotzkroete hat behauptet:
Man müsste aber die c++ stdlib noch dazu linken können.
Habe ich schon gemacht. g++ ist ja nur ein frontend für gcc ;)

Ich hab mal dein Beispiel aus dem Anderen Thread genommen, und man sehe und staune:
Code:
foo@bar:~$ cat make_my_day.cc 
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

int main ()
{

cout<< "Hallo";
return 0;
system ("pause");
}
foo@bar:~$ gcc -o blubb -lstdc++ make_my_day.cc 
foo@bar:~$ ./blubb 
Hallo

Was sagt uns das?
Der C++-Compiler von gcc kann C++-Funktionen aufrufen.
Versuchen wir die selbe Datei nämlich mit dem C-Compiler zu übersetzen, treten Fehler auf (was völlig verständlich ist.)

Code:
foo@bar:~$ gcc -x c make_my_day.cc 
make_my_day.cc:1:20: error: iostream: Datei oder Verzeichnis nicht gefunden
make_my_day.cc:2:18: error: string: Datei oder Verzeichnis nicht gefunden
make_my_day.cc:4: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘namespace’
make_my_day.cc: In function ‘main’:
make_my_day.cc:9: error: ‘cout’ undeclared (first use in this function)
make_my_day.cc:9: error: (Each undeclared identifier is reported only once
make_my_day.cc:9: error: for each function it appears in.)

gcc sucht den passenden Compiler anhand der Dateiendung selbst aus, wenn man ihm nichts gegenteiliges angibt.
 
Ja, ist ja auch in der manpage beschrieben ;)
Kann iirc auch assembler ohne weitere commandline Optionen assemblen.
 
Herr Nilsson schrieb:
Mea culpa: Der gcc C-Compiler kann es selbstverständlich übersetzen, aber es kann dann nichts mehr gelinkt werden: [...]
Das war richtig.
kotzkroete schrieb:
Man müsste aber die c++ stdlib noch dazu linken können.
Habe ich schon gemacht. g++ ist ja nur ein frontend für gcc
Herr Nilsson schrieb:
<OT>@kotzkroete:
Ich müßte mich schon ziemlich irren, wenn das klappen sollte; wir können ja hier weitermachen. Zeig' mir mal, wie Du das gemacht hast.</OT>
Das war falsch.

Code:
$ cat hallo_welt.c
#ifdef __cplusplus
#  error "Hier wird ein C++-Compiler verwendet!";
#endif

int main(void)
{
    int a = 1;
    return --a;
}

$ gcc -o hallo_welt_c hallo_welt.c
Weil hier ein C-Compiler läuft, wurde das "#ifdef __cplusplus" ignoriert. Die generierten Aufrufe sind C-Aufrufe und wurden zur Einleitung schon gezeigt.

Code:
$ ln -s hallo_welt.c hallo_welt.cc
$ gcc -o hallo_welt_c++ hallo_welt.cc
hallo_welt.cc:2:4: #error "Hier wird ein C++-Compiler verwendet!";
Das gcc-Programm ist kein ausschließlicher C-Compiler, sondern wählt den Compiler in Abhängigkeit von der Endung aus. Er kann auch als C++-Compiler eingesetzt werden.

In den Info-Seiten steht unter 1 Programming Languages Supported by GCC:
Most of the compilers for languages other than C have their own names.
The C++ compiler is G++, the Ada compiler is GNAT, and so on. When we
talk about compiling one of those languages, we might refer to that
compiler by its own name, or as GCC. Either is correct.
Ich sehe die Sache mal als Optimist und Pragmatiker: Als Optimist sage ich natürlich nicht, daß wir uns alle geirrt haben, sondern daß wir alle recht hatten! Und als Pragmatiker will ich mich nicht darüber ewig streiten, weil es noch anderes zu tun gibt: Either is correct. Have a nice day! 8)
 
Zuletzt bearbeitet:
Herr Nilsson schrieb:
Mea culpa: Der gcc C-Compiler kann es selbstverständlich übersetzen, aber es kann dann nichts mehr gelinkt werden: [...]
Das war richtig.
Nein, das war falsch.
Ein C-Compiler kann es überhaupt nicht selbstverständlich übersetzen, er kann es sogar gar nicht übersetzen.
Für C++-Code braucht man einen C++-Compiler, den hat gcc ja auch aufgerufen.
 
Zuletzt bearbeitet:
@Mµ*e^13.5_?¿:

Wie gefährlich doch (Programmier-)Sprachen sein können...

Ergänze mich bitte, falls ich etwas vergessen haben sollte. Das "kartoffel200"-Beispiel enthielt u.a. "#include <iostream>". Wenn nicht dort, so doch bestimmt in den anderen hiervon nachgeladenen C++-Headern werden zumindest Dinge wie "namespaces", "exceptions", Klassen, Vererbung und die Überladung des von "kartoffel200" verwendeten "<<"-Operators vorkommen; für die zahlreichen Abwandlungen des Operators vermutlich sogar "templates". Diese Dinge sind keine Bestandteile des C-Standards, und nicht nur Du sondern genaugenommen auch ich gehe davon aus, daß ein C-Compiler hier in den Streik treten wird.

Fälschlicherweise habe ich bis vor kurzem "gcc" mit "C-Compiler" gleichgesetzt und wurde damit an einigen Stellen unpräzise/unkorrekt. Aber ich glaube nicht, daß meine Kernaussage damit entkräftet ist: Alles, ob der Quellcode nun C++-Merkmale enthält oder nicht, was mit einem C++-Compiler[1] übersetzt wurde[2], besitzt auch die C++-Typsignaturen. Als kleinster gemeinsamer Nenner kommt man also um den Punkt, daß ein C-Compiler nur schlecht C++-Funktionen aufrufen kann, nicht herum. Beim "kartoffel200"-Beispiel kamen zusätzlich noch quellcodeabhängige Gründe hinzu.

Da mein Hinweis aber nicht quellcodeabhängig ist, halte ich ihn für das stärkste Argument.

Bevor noch der Hinweis von jemand anderem kommt: Ich kann mir schon vorstellen, daß man unter C natürlich alles mögliche aufrufen kann, sofern man Inline-Assembler, Typumwandlung von Funktionszeigern (diese könnte man z.B. als etwas dem "void"-Zeiger analogem aus dem Assembler-Teil beziehen) oder irgendwelche anderen "unsauberen" Tricks anwendet. Aber das kann ja wohl nicht als ernstgemeinter Vorschlag angeführt werden.

[1] Ich hoffe, der g++ wird nicht in Abhängigkeit von der Dateiendung zum C-Compiler; aber in diesem Fall nenne ich keinen C++-Compiler mehr.
[2] Und die von mir schon erwähnte "linkage specification" auf den Standardwert C++ gelassen hat. Daß ein C++-Programmierer seine eigenen Funktionen nach der C-Konvention aufrufen läßt, erwarte ich im Allgemeinen nicht. Wer auf Rückwärtskompatibilität Wert legt, müßte auch in den Header-Dateien auf C++-Merkmale verzichten, und es wäre oftmals leichter, dann direkt in C zu schreiben.

Nebenbei: Was bedeutet eigentlich "Mµ*e^13.5_?¿"?
 
Die Sache mit den Typsignaturen stimmt, dagegen will ich gar nichts sagen.

Mein Nickname hat nichts besonderes zu bedeuten, ist bloß eine Aneinanderreihung von Zeichen.
 

Ähnliche Themen

"non blocking console input" wieder rückgängig machen?

Unix Webserver mit HTML Seite erstellen

Funktion nicht gefunden

Aufgabe in C

Shellskript - Fehler in Cron

Zurück
Oben