Barebones C ++ ohne Standardbibliothek?

9

Compiler wie GCC und Clang ermöglichen das Kompilieren von C ++ - Programmen ohne die C ++ - Standardbibliothek, z. Verwenden des Befehlszeilenbefehls -nostdlib . Es scheint so, als ob solche Verbindungen dich oft nicht verbinden, zum Beispiel:

%Vor%

In der Regel wird die Verknüpfung aufgrund nicht definierter Symbole wie __cxa_allocate_exception , typeinfo for int , __cxa_throw , __gxx_personality_v0 , __clang_call_terminate , __cxa_begin_catch , std::terminate() usw. nicht hergestellt.

Sogar ein einfaches

%Vor%

Fehler beim Verknüpfen mit

  

ld: warning: Eintragssymbol% ​​co_de% kann nicht gefunden werden; standardmäßig 0000000000400120

und wird vom Betriebssystem bei der Ausführung getötet. Mit _start führt der Compiler immer noch den Linker aus, der eklatant scheitert mit:

  

ld: Fehler in -c ( mytest ); Es wird keine Tabelle .eh_frame erstellt.

Ist es ein realistisches Ziel, C ++ - Anwendungen oder -Bibliotheken zu programmieren und zu kompilieren, ohne die Standardbibliothek zu verwenden und mit ihr zu verknüpfen? Wie kann ich meinen Code mit GCC oder Clang unter Linux kompilieren? Welche Kernsprachenfunktionen könnte man ohne die Standardbibliothek nicht nutzen?

    
jotik 16.05.2016, 09:01
quelle

2 Antworten

16
___ answer37250788 ___

"Standard" ist eine falsche Bezeichnung. In diesem Kontext bedeutet es nicht "die Bibliothek (Menge von Funktionen, Klassen usw.) wie durch den C ++ Standard definiert", sondern "die übliche Menge von Bibliotheken und Objekten (kompilierte Dateien in einem bestimmten Format), mit denen gcc standardmäßig verlinkt ist". Einige davon sind notwendig, damit die meisten oder sogar alle Programme funktionieren.

Wenn Sie dieses Flag verwenden, liegt es in Ihrer Verantwortung, fehlende Funktionen bereitzustellen. Es gibt mehrere Möglichkeiten, dies zu tun:

  1. Wählen Sie Bibliotheken und Objekte aus, die Ihr Programm wirklich aus dem Standardsatz benötigt. (Das ergibt wenig Sinn, da das Ergebnis höchstwahrscheinlich genauso ist wie bei den Standard-Link-Flags).
  2. Stellen Sie Ihre eigene Implementierung fehlender Funktionalität bereit.
  3. Explizit deaktivieren Sie über Compiler-Flags Sprachfeatures, die Ihr Programm nicht verwendet. Ich kenne zwei solcher Merkmale: Ausnahmen und RTTI. Dies ist erforderlich, da der Compiler ausnahmebedingten Code und RTTI-Informationen generieren muss, selbst wenn diese Funktionen in diesem Modul nicht explizit verwendet werden.
  4. .
___ qstntxt ___

Compiler wie GCC und Clang ermöglichen das Kompilieren von C ++ - Programmen ohne die C ++ - Standardbibliothek, z. Verwenden des Befehlszeilenbefehls -nostdlib . Es scheint so, als ob solche Verbindungen dich oft nicht verbinden, zum Beispiel:

%Vor%

In der Regel wird die Verknüpfung aufgrund nicht definierter Symbole wie crti.o , crtbegin.o , crtend.o , crtn.o , crti.o , crtend.o , crtbegin.o usw. nicht hergestellt.

Sogar ein einfaches

%Vor%

Fehler beim Verknüpfen mit

  

ld: warning: Eintragssymbol% ​​co_de% kann nicht gefunden werden; standardmäßig 0000000000400120

und wird vom Betriebssystem bei der Ausführung getötet. Mit crtend.o führt der Compiler immer noch den Linker aus, der eklatant scheitert mit:

  

ld: Fehler in -print-file-name= ( .init ); Es wird keine Tabelle .fini erstellt.

Ist es ein realistisches Ziel, C ++ - Anwendungen oder -Bibliotheken zu programmieren und zu kompilieren, ohne die Standardbibliothek zu verwenden und mit ihr zu verknüpfen? Wie kann ich meinen Code mit GCC oder Clang unter Linux kompilieren? Welche Kernsprachenfunktionen könnte man ohne die Standardbibliothek nicht nutzen?

    
___ answer37250543 ___

Sie werden im Prinzip alle Ihre Fragen auf osdev.org finden, aber ich gebe trotzdem eine kurze Zusammenfassung.

Wenn Sie GCC crtbegin.o angeben, sagen Sie "keine Startup- oder Bibliotheksdateien ". Dies beinhaltet:

  • crtend.o , libgcc , -lgcc und -nostdlib . Im Allgemeinen kümmern sich Kernel-Entwickler nur darum, libstdc++ und -fno-rtti zu implementieren und GCC liefert -fno-exceptions und %code% , indem sie %code% an den Linker übergeben. Im Allgemeinen sind dies nur Stubs, die aus %code% und %code% bestehen, was Platz für GCC lässt, um den Inhalt von %code% bzw. %code% zu verschieben. Diese Dateien sind für den Aufruf globaler Konstruktoren / Destruktoren erforderlich.
  • Sie können nicht vermeiden, %code% (das `low-level runtime library " ( %code% ), denn selbst wenn Sie %code% GCC übergeben, werden bei jeder Verwendung Aufrufe an ihre Funktionen gesendet, was zu unerklärlichen Verknüpfungen führt Fehler scheinbar ohne Grund Dies ist auch der Fall, wenn Sie eine C-Bibliothek implementieren / portieren.
  • Sie brauchen %code% no nicht, aber normalerweise wollen es Kernel-Entwickler. Eine C-Bibliothek portieren und dann die C ++ - Standardbibliothek von Grund auf neu implementieren, ist eine äußerst schwierige Aufgabe.

Da Sie nur die "Standard-Bibliothek" loswerden wollen, aber libc (auf einem Linux-System) beibehalten, programmieren Sie im Wesentlichen C ++ mit nur einer C-Bibliothek. Natürlich ist nichts falsch daran und du tust es, aber letztlich sehe ich den Punkt nicht, außer du planst die Entwicklung eines Kernels.

Pflichtlektüre:

OSDevs C ++ Seite - Wenn Sie sich wirklich um RTTI / Exception Support kümmern, ist es ärgerlicher zu implementieren als es klingt . In der Regel übergeben Personen einfach %code% oder %code% und machen sich dann Gedanken darüber oder gar nicht.

    
___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll. ___ tag123std ___ std ist der Name des Namespace, der die C ++ - Standardbibliothek enthält. Verwenden Sie mit dem [C ++] -Tag ___ qstnhdr ___ Barebones C ++ ohne Standardbibliothek? ___
user6339982 16.05.2016, 09:22
quelle
5

"Standard" ist eine falsche Bezeichnung. In diesem Kontext bedeutet es nicht "die Bibliothek (Menge von Funktionen, Klassen usw.) wie durch den C ++ Standard definiert", sondern "die übliche Menge von Bibliotheken und Objekten (kompilierte Dateien in einem bestimmten Format), mit denen gcc standardmäßig verlinkt ist". Einige davon sind notwendig, damit die meisten oder sogar alle Programme funktionieren.

Wenn Sie dieses Flag verwenden, liegt es in Ihrer Verantwortung, fehlende Funktionen bereitzustellen. Es gibt mehrere Möglichkeiten, dies zu tun:

  1. Wählen Sie Bibliotheken und Objekte aus, die Ihr Programm wirklich aus dem Standardsatz benötigt. (Das ergibt wenig Sinn, da das Ergebnis höchstwahrscheinlich genauso ist wie bei den Standard-Link-Flags).
  2. Stellen Sie Ihre eigene Implementierung fehlender Funktionalität bereit.
  3. Explizit deaktivieren Sie über Compiler-Flags Sprachfeatures, die Ihr Programm nicht verwendet. Ich kenne zwei solcher Merkmale: Ausnahmen und RTTI. Dies ist erforderlich, da der Compiler ausnahmebedingten Code und RTTI-Informationen generieren muss, selbst wenn diese Funktionen in diesem Modul nicht explizit verwendet werden.
  4. .
n.m. 16.05.2016 09:35
quelle

Tags und Links