Der g++ aus dem GCC-ARM-Embedded funktioniert ganz wunderbar, wenn man
ein paar Feinheiten beachtet. Die Behauptung, C++ sei ineffizient ist
völliger Unsinn; sofern man richtig codet ist das Ergebnis (mindestens)
so effizient wie das C-Äquivalent. Man kann immernoch genau so gut
kontrollieren was wo im Speicher passiert, man sollte sich nur eben ein
bisschen auskennen wie Automatic Storage funktioniert.
Es schadet aber auch nicht, sich den erzeugten Assembler-Code mal
anzusehen.
Wichtig ist, aus dem Startup-Code vor dem Aufruf der main()-Funktion
die Konstrukturen der globalen Objekt-Instanzen aufzurufen; die
__libc_init_array Funktion aus der libc (wird automatisch dazugelinkt)
macht das.
Man sollte irgendwo im Code folgendes unterbringen:
1 | extern "C"
|
2 | int atexit() {
|
3 | return 0;
|
4 | }
|
5 | extern "C" void __cxa_pure_virtual () {
|
6 | while(1);
|
7 | }
|
Dies verhindet das dazulinken des riesigen Exception-Handling-Codes aus
der libstdc++, falls man virtuelle Funktionen verwendet (stattdessen
gibts halt eine Endlosschleife, falls man es irgendwie schafft eine rein
virtuelle Funktion aufzurufen). Außerdem sollte man per "-fno-rtti
-fno-exceptions" RTTI und Exceptions abschalten. "-ffunction-sections
-fdata-sections" für den Compiler und "-Wl,--gc-sections" für den
Linker, um unbenutzten Code/Variablen wegzuoptimieren.