Warum stellen C-Compiler Unterstriche vor externe Namen?

Lesezeit: 5 Minuten

Benutzeravatar von Michael Burr
Michael Burr

Ich arbeite schon so lange in C, dass die Tatsache, dass Compiler normalerweise einen Unterstrich am Anfang eines an extern wird nur verstanden … Eine andere SO-Frage heute hat mich jedoch dazu gebracht, mich über den wahren Grund zu wundern, warum der Unterstrich hinzugefügt wird. EIN Wikipedia-Artikel behauptet, dass ein Grund ist:

Es war üblich, dass C-Compiler allen externen Bereichsprogrammkennungen einen führenden Unterstrich voranstellten, um Konflikte mit Beiträgen der Laufzeitsprachenunterstützung zu vermeiden

Ich denke, es gibt zumindest einen Kern Wahrheit, aber es scheint auch die Frage nicht wirklich zu beantworten, da es nicht viel hilft, Konflikte zu verhindern, wenn der Unterstrich zu allen Extern hinzugefügt wird.

Hat jemand gute Informationen über die Gründe für den führenden Unterstrich?

Ist der hinzugefügte Unterstrich Teil des Grundes, dass das Unix creat() Systemaufruf endet nicht mit ‘e’? Ich habe gehört, dass Early Linker auf einigen Plattformen ein Limit von 6 Zeichen für Namen hatten. Wenn das der Fall ist, dann scheint es eine geradezu verrückte Idee zu sein, externen Namen einen Unterstrich voranzustellen (jetzt habe ich nur noch 5 Zeichen zum Spielen …).

  • Es sollte beachtet werden, dass dieses Verhalten auf modernen ELF-Systemen nicht praktiziert wird. Es war anscheinend auf Aout / Coff-Plattformen üblich.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    7. Dezember 2010 um 1:33 Uhr

  • Warum macht Clang das unter OS X? wie kann ich es abschalten?

    – MarcusJ

    29. Mai 2016 um 2:07 Uhr

Es war üblich, dass C-Compiler allen externen Bereichsprogrammkennungen einen führenden Unterstrich voranstellten, um Konflikte mit Beiträgen der Laufzeitsprachenunterstützung zu vermeiden

Wenn die Laufzeitunterstützung vom Compiler bereitgestellt wird, wäre es sinnvoller, den wenigen externen Bezeichnern in der Laufzeitunterstützung stattdessen einen Unterstrich voranzustellen!

Als C-Compiler zum ersten Mal auftauchten, war die grundlegende Alternative zum Programmieren in C auf diesen Plattformen das Programmieren in Assemblersprache, und es war (und ist es gelegentlich immer noch) nützlich, in Assembler und C geschriebene Objektdateien miteinander zu verknüpfen. Also wirklich (IMHO) führend Unterstrich zu externen C-Bezeichnern hinzugefügt wurde, um Konflikte mit den Bezeichnern in zu vermeiden dein eigenes Assembler-Code.

(Siehe auch GCCs asm Etikettenerweiterung; und beachten Sie, dass dieser vorangestellte Unterstrich als einfache Form von angesehen werden kann Namensverstümmelung. Kompliziertere Sprachen wie C++ verwenden kompliziertere Namensfehler, aber hier fing es an.)

  • Ich mag das sarkastische “GCC hat noch nicht die Fähigkeit, statische Variablen in Registern zu speichern. Vielleicht wird das hinzugefügt.” Kommentar im verlinkten Dokument.

    – Michael Burr

    13. April 2010 um 18:59 Uhr

  • @MichaelBurr: Es ist möglicherweise nicht sarkastisch. Auf einigen Systemen können Sie ein globales Register als Zeiger auf einen Speicherbereich reservieren (z R9 in einigen Variationen von ARM EABI für den statischen Basiszeiger).

    – Igor Skochinsky

    12. September 2013 um 22:56 Uhr

  • Ein weiterer Grund für das Voranstellen _ zu C-Namen soll sicherstellen, dass sie nicht mit Registernamen kollidieren. z.B static int eax, r0; ist in C zulässig, und einige Assembler-Syntaxen schmücken Registernamen nicht mit irgendetwas.

    – Peter Cordes

    26. Januar 2020 um 17:54 Uhr

alvins Benutzeravatar
alvin

Wenn der c-Compiler jedem Symbol immer einen Unterstrich vorangestellt hat, kann der Start-/C-Laufzeitcode (der normalerweise in Assembler geschrieben ist) Beschriftungen und Symbole verwenden, die nicht mit einem Unterstrich beginnen (wie das Symbol ‘start ‘).

selbst wenn Sie eine start()-Funktion in den C-Code schreiben, wird sie als _start in der Ausgabe von object/asm generiert. (Beachten Sie, dass es in diesem Fall keine Möglichkeit für den C-Code gibt, ein Symbol zu generieren, das nicht mit einem Unterstrich beginnt), sodass sich der Startcoder keine Gedanken darüber machen muss, obskure, unwahrscheinliche Symbole (wie $_dontuse42%$) für jedes von zu erfinden seine/ihre globalen Variablen/Labels.

Der Linker wird sich also nicht über einen Namenskonflikt beschweren, und der Programmierer ist glücklich. 🙂

Folgendes unterscheidet sich von der Praxis des Compilers, der seinen Ausgabeformaten einen Unterstrich voranstellt.

Diese Praxis wurde später als Teil der C- und C++-Sprachstandards kodifiziert, in denen die Verwendung von führenden Unterstrichen für die Implementierung reserviert war.

Das ist eine Konvention, die für die C-Systembibliotheken und andere Systemkomponenten befolgt wird. (und für Dinge wie __FILE__ usw.).

(Beachten Sie, dass ein solches Symbol (z. B.: _time) in der generierten Ausgabe zu 2 führenden Unterstrichen (__time) führen kann.)

Was ich immer höre ist, Namenskonflikte zu vermeiden. Nicht für andere externe Variablen, sondern mehr, damit es bei Verwendung einer Bibliothek hoffentlich nicht zu Konflikten mit den Variablennamen des Benutzercodes kommt.

Die Hauptfunktion ist nicht der eigentliche Einstiegspunkt einer ausführbaren Datei. Einige statisch gelinkte Dateien haben den eigentlichen Einstiegspunkt, der schließlich main aufruft, und diese statisch gelinkten Dateien besitzen den Namespace, der nicht mit einem Unterstrich beginnt. Auf meinem System befinden sich in /usr/lib unter anderem gcrt1.o, crt1.o und dylib1.o. Jeder von ihnen hat eine “Start”-Funktion ohne Unterstrich, die schließlich den Einstiegspunkt “_main” aufruft. Alles andere außer diesen Dateien hat einen externen Geltungsbereich. Die Geschichte hat mit dem Mischen von Assembler und C in einem Projekt zu tun, bei dem alles C als extern betrachtet wurde.

Aus Wikipedia:

Es war üblich, dass C-Compiler allen externen Bereichsprogrammkennungen einen führenden Unterstrich voranstellten, um Konflikte mit Beiträgen der Laufzeitsprachenunterstützung zu vermeiden. Wenn der C/C++-Compiler als Teil des Übersetzungsprozesses Namen in die externe Verknüpfung einfügen musste, wurden diese Namen außerdem oft durch eine Kombination aus mehreren führenden oder nachgestellten Unterstrichen unterschieden.

Diese Praxis wurde später als Teil der C- und C++-Sprachstandards kodifiziert, in denen die Verwendung von führenden Unterstrichen für die Implementierung reserviert war.

1398400cookie-checkWarum stellen C-Compiler Unterstriche vor externe Namen?

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

Privacy policy