Wo sind die Funktionen in der C-Standardbibliothek definiert?

Lesezeit: 5 Minuten

Benutzer-Avatar
Tyler

Der Quellcode interessiert mich nicht, ich möchte wissen, wie der C-Compiler (GCC) die Funktionen eigentlich findet. Wie in, wenn der Präprozessor sieht, dass ich eingeschlossen habe stdio.hwo sucht es nach den Dateien, die die Funktionskörper definieren?

Bearbeiten

Ich sollte wahrscheinlich auch sagen, dass ich Ubuntu 12.04 verwende, aber wenn es eine allgemeine Antwort gibt, würde das auch funktionieren.

  • Das Compiler benötigt nur die Header-Dateien. Das Linkerbenötigt jedoch Objekt- oder Bibliotheksdateien.

    – Joey

    7. März 2014 um 6:18 Uhr

  • verwandt: stackoverflow.com/questions/11481154/…

    – Ciro Santilli Путлер Капут 六四事

    18. April 2016 um 17:44 Uhr

Benutzer-Avatar
Alex D

gcc kommt mit (binären) Objektdateien (nicht C-Quelldateien), die Implementierungen aller C-Standardfunktionen enthalten. Wenn Sie verwenden gcc um Objektdateien zu einer ausführbaren Datei zu verknüpfen, dem Linker automatisch enthält die Objektdateien, die die Standardbibliotheksfunktionen implementieren. Laut diesem Thread wird wahrscheinlich diese Standardobjektdatei aufgerufen libc.a oder libc.so.

Sagen Sie, Sie schließen einen Anruf an ein printf in deinem Programm. Wenn der Linker versucht aufzulösen, wohin dieser Aufruf gehen soll, findet er die Definition von printf in libc.aund machen Sie dort Ihren Funktionsaufrufpunkt.

Ansehen http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html und beachten Sie die -nostdlib und -nodefaultlibs Optionen. Sie können diese Optionen verwenden, um dies zu erkennen gccDer Linker von nicht um standardmäßig die Objektdateien der Standardbibliothek einzuschließen.

  • So schließt der Linker automatisch Objektdateien ein, die implementieren alle die Standardbibliothek funktioniert jedes Mal? Wenn ja, welchen Sinn hat es, verschiedene Funktionen mit verschiedenen Header-Dateien zu verknüpfen, wenn sie sowieso alle enthalten sind?

    – Tyler

    8. März 2014 um 22:37 Uhr

  • Das Objektdateien werden von der verwendet gcc Linker. Das Header-Dateien werden von der verwendet Compiler. Der Compiler muss die Header sehen, damit er die Funktionssignaturen kennt und somit 1) den Code typisieren kann und 2) den richtigen Code zum Übergeben von Argumenten und zum Abrufen des Rückgabewerts generieren kann. Warum haben sie nicht die Unterschriften für alle die Standard-Bibliotheksfunktionen in einer einzigen Header-Datei? Nun, zum einen wäre es nicht mit dem C-Standard konform, da der C-Standard tatsächlich definiert, was die Standard-Header-Dateien sein sollten. Zum anderen würde es die Kompilierungszeiten verlangsamen.

    – Alex D

    9. März 2014 um 19:56 Uhr

  • Außerdem, @Tyler, enthält der Linker keine Objektdateien aus einer statischen Bibliothek, es sei denn, sie werden benötigt. Die .a-Datei ist eine indizierte Bibliothek separater Objektmodule, und der Linker enthält nur diejenigen, die ein undefiniertes Symbol auflösen (und einige davon können auf neue undefinierte Symbole verweisen, sodass er weiterläuft). Im Fall einer .so-Datei wird die gesamte Bibliothek zur Laufzeit geladen, daher trifft dies nicht zu.

    – Gregor

    16. Juni 2015 um 17:30 Uhr

Benutzer-Avatar
devnull

gcc erhält die Funktionsdefinitionen aus der C-Bibliothek. Den Pfad könntest du damit bestimmen gcc würde standardmäßig danach suchen, indem Sie sagen:

ld --verbose | grep SEARCH_DIR

Dies führt zu /usr/lib auf meinem System.

Versuchen wir herauszufinden, ob die Bibliothek das Symbol für eine Standardfunktion enthält, sagen wir scanf:

nm -A /usr/lib/libc.so | grep scanf

Die Ergebnisse umfassen:

/lib/libc.so:0000000000042a90 T scanf

Betrachten Sie ein kleines Beispiel:

#include <stdio.h>

int main() {
  printf("Hello World!\n");
  return 0;
}

Nennen wir es i.c:

$ gcc i.c              # Compile
$ ldd ./a.out          # Try to find dependencies
./a.out:
        -lc.12 => /usr/lib/libc.so.12

Der letzte Befehl impliziert im Wesentlichen, dass die Binärdatei davon abhängt /usr/lib/libc.so.12
und dass Sie die Definitionen der im Code verwendeten Funktionen darin finden würden.

Ihre Frage hat damit zu tun, wo GCC nach Header-Dateien sucht. Es durchsucht die standardmäßigen Include-Verzeichnisse. Du wirst vielleicht finden dieser Faden um nützlich zu sein:

Mit verschiedenen Optionen (wie -I und -I- und -isystem) können Sie viele verschiedene Inklusionsfunktionen angeben. Grundsätzlich werden die mit -I angegebenen Verzeichnisse vor den mit -isystem angegebenen Verzeichnissen durchsucht, die wiederum vor denen im “Standardsystem enthaltene Verzeichnisse” durchsucht werden (zumindest nach meinen Tests). Der Unterschied besteht darin, dass -I für jede #include-Direktive verwendet werden kann, aber -isystem nur für #include <...> verwendet wird. Es wird jedoch empfohlen, -I nur für #include “… ” Direktiven wegen der Suchreihenfolge. Die Verwendung von -I- gibt Ihnen wirklich viel Kontrolle, da jedes -I, das vor -I- verwendet wurde, nur nach #include “…” gesucht wird, während jedes -I, das nach -I- verwendet wurde, nach einer beliebigen #include-Direktive durchsucht wird . Außerdem bedeutet die Verwendung von -I-, dass das aktuelle Verzeichnis nicht nach enthaltenen Dateien durchsucht wird, es sei denn, Sie geben auch -I an. (Durchsuchen Sie das aktuelle Verzeichnis).

Wenn Sie eine Liste der standardmäßig unterstützten Suchverzeichnisse erhalten möchten, führen Sie diesen Befehl aus: cpp -v < /dev/null Dies führt den GNU-C-Präprozessor ohne Eingabe aus; dabei werden (anhand des -v-Flags) die Suchpfade des Einschlussverzeichnisses gedruckt. Sie sollten Sätze wie „#include <...> Suche beginnt hier:“ sehen, gefolgt von einer Liste von Verzeichnissen. Dies sind Ihre standardmäßigen Einschlusssuchpfade in der Reihenfolge, in der sie durchsucht werden.

  • Dies ist etwas tangential zu dem Ort, an dem die Bibliotheken gefunden werden, obwohl die Header standardmäßig in gefunden werden /some/path/includedie Bibliotheken befinden sich normalerweise in /some/path/lib.

    – Jonathan Leffler

    7. März 2014 um 3:56 Uhr

Dein libc (oder libstdc++ für C++) kann sich in beiden befinden /usr/lib oder /usr/lib64 auf Linux. Diese sind gemeinsam genutzte Bibliotheken und Sie können die ändern LD_LIBRARY_PATH -Variable, um anzugeben, in welchen Verzeichnissen sie gesucht werden. Ein praktisches Beispiel wäre, dass Sie eine lokale Kopie von gcc installieren, und es besteht die Möglichkeit, dass diese eine aktualisierte Version der Standardbibliothek im Gegensatz zu Ihrem System enthält, sodass Sie möchten, dass Ihr lokaler gcc dies tut Beginnen Sie stattdessen damit, dh export LD_LIBRARY_PATH=/home/user/local-install/gcc/lib64

Es untersucht die Bibliothekspfade, die von der Umgebungsvariablen festgelegt werden.

Weiterlesen: http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html

  • Er fragt nicht wo gcc findet die Standard-Header. Er fragt, wo es die findet Körper dieser Funktionen.

    – Alex D

    7. März 2014 um 3:48 Uhr

  • Er fragt nicht wo gcc findet die Standard-Header. Er fragt, wo es die findet Körper dieser Funktionen.

    – Alex D

    7. März 2014 um 3:48 Uhr

1252790cookie-checkWo sind die Funktionen in der C-Standardbibliothek definiert?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy