2009-06-02 32 views
63

Ich bin mir bewusst, dass GCC auf den meisten GNU/Linux-Systemen über die Befehlszeile (im Gegensatz zu "gcc") mit dem Namen "cc" aufgerufen werden kann. Gibt es einen Unterschied im Verhalten von GCC, wenn es auf die eine oder andere Weise aufgerufen wird?Aufruf von GCC als "cc" gegen "gcc"

Zum Beispiel weiß ich, dass das Aufrufen von GCC durch den Namen "g ++" anstelle von "gcc" bewirkt, dass sich GCC anders verhält (es behandelt .c-Dateien als C++ - Quelle und -Links in der C++ - Standardbibliothek). Gibt es einen ähnlichen Unterschied im Verhalten zwischen "gcc" und "cc"?

EDIT: Keiner der bisher eingegangenen Antworten gab ein definitive „ja“ oder „nein“, ob GCC anders verhalten, wenn im Vergleich zu dem anderen Art und Weise aufgerufen. Die Idee, in die Quelle zu tauchen, um ihr Verhalten zu überprüfen, führte mich jedoch auf diesen Pfad. Basierend auf dem, was ich dort gefunden habe, glaube ich jetzt, dass die Antwort lautet:

Nein. GCC verhält sich gleich, unabhängig davon, ob es über "gcc" oder "cc" aufgerufen wird.

+0

Scheint das selbe aa gawk vs awk zu sein, gmake vs. machen etc. Ich würde mich auf ihnen verkaufen, die immer gleich sind. Auf Solaris-Systemen höre ich, dass make anders ist als gmake (gnu make). Vielleicht gelten auf einem System ähnliche Dinge für gcc vs cc. –

Antwort

33

Für grinst, ich habe gerade aufgespürt, wie argv[0] von innen verwendet wird gcc (main.c ->top_lev.c ->opts.c ->langhooks.c) und es scheint, dass argv[0] derzeit für nichts mehr verwendet wird als malloc etwas zu berichten, wenn es fehlschlägt. Es scheint keine Verhaltensänderung zu geben, wenn argv[0] etwas anderes als gcc ist.

+2

Das einzige Problem, das ich damit habe, ist, dass "cc --version" gibt * etwas * andere Ausgabe von "gcc --version" (es sagt "cc" statt "gcc"). Also * irgendwas * muss da argv [0] sehen. –

+13

Ihre Antwort motivierte mich, selbst in den Quellcode zu schauen. Ich habe festgestellt, dass argv [0] zu "programname" zugewiesen wird, was dazu führt, dass es an andere Funktionen weitergegeben wird (und in der Umgebung gespeichert wird). Obwohl ich keine * erschöpfende * Suche durchgeführt habe, wird sie, wie ich sehen kann, nur für Anzeigezwecke verwendet (z. B. in der Ausgabe "-version", "Verwendung", Fehlermeldungen usw.). –

+0

Ich habe gerade festgestellt, dass dies nur gilt, wenn cc und gcc die gleiche ausführbare Datei sind. Kann es passieren, dass das System verschiedene Binärdateien hat? Stellen Sie sich vor, dass cc mit einer Clam-Binärdatei und gcc mit gcc verknüpft sein könnte. Ehrliche Frage, ich habe keine Ahnung. –

12

auf meinem Mac aus man gcc:

In Apple-Version von GCC, beide cc und gcc sind eigentlich symbolische Verbindungen zu einem Compiler wie gcc-Version genannt. In ähnlicher Weise sind C++ und g ++ Links zu einem Compiler namens g ++ - Version.

Basierend darauf würde ich annehmen, dass sich cc und gcc auf die gleiche Weise verhalten.

+17

Es ist in Unix-Welt üblich, mehrere Links auf dieselbe ausführbare Datei zu setzen, und es ändert einige Standardeinstellungen entsprechend dem Namen, der beim Aufruf verwendet wurde. – Javier

+0

Woah und ein Downvote ohne Erklärung - sehr hilfreich ... vielleicht haben sie etwas nicht gefallen? – stefanB

+3

vielleicht ein Apple-Hasser? :) –

1

Wenn man bedenkt, dass dies von UNIX kommt, würde ich sagen, dass "cc" der generische Name ist und "gcc" der eigentliche Compiler ist. d. h. "gcc" stellt "cc" bereit, so dass ein Programm, das nach "cc" sucht, "cc" finden und verwenden würde, glückselig unwissend über den tatsächlich verwendeten Compiler.

Außerdem sollten UNIX-Programme den tatsächlichen Namen, der zum Aufrufen verwendet wurde, nicht kennen (denke an Windows Desktop-Verknüpfungen - es macht keinen Sinn zu überprüfen, wie die Verknüpfung aufgerufen wurde), also, nein, "gcc" und " cc "mach dasselbe, wenn" cc "ein Link zu" gcc "ist.

Es sei denn natürlich, "cc" ist kein Symlink, sondern ein Shellskript, das gcc aufruft.

+2

gzip prüft seinen Namen. Wenn sein Name gunzip ist, nimmt er -d an. – Joshua

+3

"Außerdem sollten UNIX-Programme den tatsächlichen Namen nicht kennen, mit dem sie aufgerufen werden." Das stimmt absolut nicht. Haben Sie schon einmal von Multi-Call-Binaries gehört? I.e. Busybox? http://www.busybox.net/ – mateusza

+2

und schließlich ist "sh" in der Regel ein Symlink zu "bash", was dazu führt, dass es sich wie eine POSIX-Shell verhält. sh <-> bash ist eigentlich sehr ähnlich wie cc <-> gcc. –

14

Es sieht für mich so aus, dass cc (Link zu einer alten SUS-Spezifikation) die herstellerneutrale Schnittstelle zum Compiler des Systems sein soll. Es ist, als Vermächtnis markiert:

Das c89 Dienstprogramm eine Schnittstelle zum ISO-C-Standard bietet, aber der cc-Dienstprogramm einen unbestimmten Dialekt der Sprache C akzeptiert: es Standard C, Common-Nutzung C oder eine andere Variante kann sein . Portable C-Programme sollten so geschrieben werden, dass sie dem ISO-C-Standard entsprechen und mit c89 kompiliert werden.

POSIX hat ein Programm namens c99, die ich glaube, dass der Nachfolger von c89 ist. Es heißt

Das c99-Dienstprogramm basiert auf dem c89-Dienstprogramm, das ursprünglich in den ISO-Standard POSIX-2: 1993 eingeführt wurde. Einige der Änderungen von c89 enthalten die Änderung des Inhalts des Abschnitts Standardbibliotheken, um neue Kopfzeilen und Optionen zu berücksichtigen. B. dem Operanden -l rt hinzugefügt und der Tracefunktion -l für die Tracing-Funktionen hinzugefügt.

Ich bin nicht wirklich vertraut zu all den verschiedenen Standards, aber es sieht aus wie die jüngere SUSv3 (POSIX:2004) und die noch jüngeren POSIX:2008 (scheint noch nicht eine SUS-Nummer haben) nicht angeben ein Dienstprogramm namens cc mehr, aber nur das Dienstprogramm namens c99. Übrigens enthält mein Linux-System (Arch_Linux) eine Hilfeseite von c99, aber nicht c89, sondern enthält nur ein Dienstprogramm namens cc, aber weder c89 noch c99. Viel Verwirrung drin :)

+1

Interessanter Link. Jemand sollte wahrscheinlich den GNU Leuten davon erzählen, weil es immer noch "cc" als Standard aufruft, wenn Sie $ {CC} nicht überschreiben. Offensichtlich sollten sie eines der anderen Dienstprogramme als Standard verwenden. Es scheint, dass c89 * sollte der bevorzugte Nutzen nach dem Standard sein. –

+1

OTOH, da das 1997 geschrieben wurde, sollte heutzutage vielleicht das bevorzugte Dienstprogramm c99 sein. –

+1

ja, SUSv3 enthält c89 nicht mehr. nur das alte, mit dem ich verlinkt habe, empfahl es (SUSv2) –

3

cc ist nur die UNIX-Methode des Aufrufs des Compilers, es wird auf allen Unices funktionieren.

+2

Dies geht nicht auf die Frage ein. – bortzmeyer

+3

Eigentlich tut es, cc bedeutet "C-Compiler" auf Unix, nichts mehr. – ismail

+1

Der Fragesteller fragte auch nach dem Unterschied von cc und gcc. Dies dient auch als Antwort und adressiert die Frage, imo –

2

Nichts in der GCC-Dokumentation gibt an, dass GCC anders verhalten würde, wenn sein Name der ausführbaren Datei nicht gcc ist aber cc. Die GNU-Fortran-Compiler selbst mentions that:

Eine Version des gcc-Befehl (die auch als cc-Befehl des Systems installiert werden könnte)

2

Ich verwende UNIX seit 1983, und der C-Compiler hieß damals cc. Es ist schön zu denken, dass vielleicht ein Make-Datei ich damals schrieb noch auf dem neuesten Linux-Distribution heute funktionieren könnte ...

+1

Nun, der Grund dafür ist, dass GNU Make die Variable $ {CC} standardmäßig auf "cc" und nicht auf "gcc" setzt (aus historischen Gründen bin ich sicher). Wenn Sie also die eingebauten Standardregeln von GNU Make verwenden, wird es mit "cc" kompiliert. Ich habe mich gefragt, ob es einen Unterschied macht, wenn ich $ {CC} an "gcc" vergebe, anstatt es einfach in Ruhe zu lassen. –

+1

Sie sollten es nur ändern, wenn Sie GCC-spezifische Funktionen auf diese Weise verwenden, wird es auf Maschinen ohne GCC nicht direkt kompilieren. –

8

ich den gleichen Zweifel heute hatte und ich versuchte es auf eigene Faust zu finden:

$ which cc 
/usr/bin/ccc 

$file /usr/bin/cc 
/usr/bin/cc: symbolic link to '/etc/alternatives/cc' 

$file /etc/alternatives/cc 
/etc/alternatives/cc: symbolic link to '/usr/bin/gcc' 

$which gcc 
/usr/bin/gcc 

Also im Grunde cc Punkte auf gcc.

Sie können auch mit cc -v und gcc -v überprüfen. Wenn sie dasselbe ausdrucken, sind sie genau gleich.

+4

Beachten Sie den Kommentar, den Javier der Antwort von stefanB gab - Unix stellt einem Programm den "Namen des Programms" als das 0te Kommandozeilenargument zur Verfügung, und viele Programme in Unix sind mit symbolischen Links aus vielen verschiedenen Namen und Ändern Sie ihr Verhalten abhängig davon, welcher Name verwendet wurde, um sie anzurufen. (Zum Beispiel ist gunzip ein Link zu gzip, aber wenn du gzip aufruft, komprimiert es Dinge und wenn du gunzip aufruft entpackst du sie.) Daher ist es durchaus plausibel, dass GCC sich anders verhält, wenn du es über einen Symlink namens 'cc' ausführst. . –

7

Auch wenn gcc unabhängig vom Wert von argv [0] arbeitet, funktioniert nicht jede Software gleich, unabhängig davon, was Sie als Compiler angeben.

Wenn zlib 1.2.5 Aufbau auf RHEL 5.5 (gcc 4.1.2):

$ md5sum $(which cc) 
69a67d3029b8ad50d41abab8d778e799 /usr/bin/cc 
$ md5sum $(which gcc) 
69a67d3029b8ad50d41abab8d778e799 /usr/bin/gcc 

Aber:

$ CC=$(which cc) ./configure 
Checking for shared library support... 
Tested /usr/bin/cc -w -c -O ztest20557.c 
Tested cc -shared -O -o ztest20557.so ztest20557.o 
/usr/bin/ld: ztest20557.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC 
ztest20557.o: could not read symbols: Bad value 
collect2: ld returned 1 exit status 
No shared library support; try without defining CC and CFLAGS 
Building static library libz.a version 1.2.5 with /usr/bin/cc. 
Checking for off64_t... Yes. 
Checking for fseeko... Yes. 
Checking for unistd.h... Yes. 
Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). 
Checking for vsnprintf() in stdio.h... Yes. 
Checking for return value of vsnprintf()... Yes. 

Und:

$ CC=$(which gcc) ./configure 
Checking for shared library support... 
Building shared library libz.so.1.2.5 with /usr/bin/gcc. 
Checking for off64_t... Yes. 
Checking for fseeko... Yes. 
Checking for unistd.h... Yes. 
Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). 
Checking for vsnprintf() in stdio.h... Yes. 
Checking for return value of vsnprintf()... Yes. 
Checking for attribute(visibility) support... Yes. 

Das Skript configure nicht Betrachten Sie die Möglichkeit, dass cc auf einem Linux-System gcc sein könnte. Sei also vorsichtig, wie weit du deine Annahmen nimmst.

+2

Dies ist selbstverständlich. Der Compiler verhält sich nicht anders. Dies ist ein Nachteil des 'configure'-Skripts. Das Skript weiß, dass 'gcc' gemeinsam genutzte Bibliotheken erzeugen kann und weiß, dass' gcc' die Option '-fPIC' benötigt, wenn gemeinsame Bibliotheken unter Linux kompiliert werden. Wenn der Compiler nicht "gcc" ist, versucht "configure" zu testen, ob der Compiler gemeinsame Bibliotheken erzeugen kann. ** Aber ** es kann nicht erraten, welche Compiler-Flags für einen Compiler benötigt werden, den es nicht kennt, also muss der Benutzer sie angeben. Sie müssen die erforderlichen Flags in der Befehlszeile angeben (z. B. über 'CFLAGS = -fPIC'). –

+3

Dies sollte eher als Vorsichtsmaßnahme denn als Antwort dienen. Das Aufrufen von gcc als cc im obigen Fall würde nicht dazu führen, dass es anders funktioniert, aber die aufrufende Software arbeitete in einer nicht intuitiven Weise, die das Auftreten von unterschiedlichem Verhalten verursachte. – ednos

2

"Nein.GCC verhält sich gleich, unabhängig davon, ob sie über 'gcc' oder 'cc' genannt wird.“

[von Original-Beitrag zitiert.]

Aufgrund meiner Erfahrung in Ubuntu 14.04, das hat nicht der Fall gewesen

wenn ich kompilieren mein Programm:..

gcc -finstrument-functions test.c 

ich im Verhalten meines Codes keine Änderung bekommen Aber wenn ich kompilieren mit

cc -finstrument-functions test.c 

Es verhält sich anders. (In beiden Fällen habe ich die entsprechenden Änderungen in meinen beschriebenen Code here eingebaut, um -Filter-Funktionen funktionieren zu lassen).

3

Dieser Thread könnte alt sein, aber ich möchte etwas hinzufügen (vielleicht wird jemand es in der Zukunft finden).

Wenn Sie dieses Programm zusammengestellt

#include <stdio.h> 
#include <stdlib.h> 

void 
myFunction(char *args) 
{ 
    char buff1[12]; 
    char buff2[4] = "ABC"; 

    strcpy(buff1,args); 

    printf("Inhalt Buffer2: %s",buff2); 

} 

int main(int argc, char *argv[]) 
{ 

    if(argc > 1) 
    { 
     myFunction(argv[1]); 
    } 
    else 
     printf("no arguments sir daimler benz"); 

    getchar(); 

    return 0; 
} 

mit „gcc“, und Sie geben es „AAAAAAAAAAAAAAAAAAAAAAAAA“ als Argument, es nicht überläuft in buffer2, während es tut, wenn Sie mit „cc“ zusammengestellt, die für mich ist ein Hinweis, dass, wenn Sie "gcc" verwendet, die Speicherverwaltung funktioniert anders, vielleicht durch Platz zwischen den Speichersegmenten der Felder buff1 & Buff2?

Vielleicht kann jemand mit mehr Erfahrung hier Licht in die Dunkelheit bringen.

+1

Ich habe es versucht (auf GCC Version 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14.04)), mit Stack Protector aus und an und beide enden entweder mit ** Segmentation Fehler ** oder ** Stack Smashing erkannt **, in Das Ende cc ist ein Link zu/etc/alternatives/cc und das ist ein Link zu/usr/bin/gcc. Wie @abcoep sagt cc und gcc unterscheidet sich nur bei der Tab-Vervollständigung (soweit ich das untersuchen konnte). – Kyslik

1

Für mein Betriebssystem (Ubuntu 14.04) cc lässt Tab Completion nicht zu, während gcc tut.