Forum: Compiler & IDEs ARM GCC mit C++


von Tobias P. (hubertus)


Lesenswert?

Hallo zusammen,
ich benutze unter Linux den ARM GCC:

arm-none-eabi-gcc

Das funktioniert gut z.B. für das Discoveryboard. Allerdings möchte ich 
jetzt einmal auch C++ verwenden. Dazu bräuchte ich ja den 
arm-none-eabi-g++, und so einer ist ja auch vorhanden, es müsste also 
gehen.

Zum Compilieren von normalem C Code habe ich ein sauberes Makefile 
geschrieben, was sehr gut funktioniert und sehr komfortabel ist. Ich 
frage mich jetzt, was ich da noch anpassen müsste, damit das mit C++ 
auch funktioniert? Was muss ich da beachten?

(Ich denke, nur die Zeile

CC = arm-none-eabi-gcc

in

CC = arm-none-eabi-g++

zu Ändern reicht nicht ;-))

Gibt es irgendwo ein minimalistisches Beispiel, wo man nachschauen 
könnte?

von (prx) A. K. (prx)


Lesenswert?

Tobias Plüss schrieb:
> zu Ändern reicht nicht ;-))

Stimmt, ganz ohne C++ Programm gehts nicht. ;-)

Die Zeile aber, die kannst du stehen lassen, denn gcc übersetzt auch C++ 
Programme, wenn er sie als solche erkennt. Allerdings kannst du ggf. ein 
paar C++ Features abschalten, wie Exception Handling und RTTI.
  -fno-exceptions
  -fno-rtti

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

http://www.mikrocontroller.net/articles/ARM_GCC#Compiler_.26_Linker_Flags 
Die Flags von da für C++ verwenden. Zwei leere Funktionen (mit extern 
"C") einbauen namens "atexit" und "__cxa_pure_virtual"

von Tobias P. (hubertus)


Lesenswert?

O.K. danke euch erstmal! Das funktioniert insofern schonmal, dass er 
meinen Code compiliert, solange ich keine C++ spezifischen Konstrukte 
brauche. :-)

Habe jetzt mal eine simple Klasse erstellt:
1
class test
2
{
3
private:
4
  int a;
5
public:
6
  test();
7
  ~test();
8
};
9
10
test::test()
11
{
12
  a = 7;
13
}
14
15
test::~test()
16
{
17
  a = 0;
18
}

und in meiner main() dann
1
test* z;
2
z = new test();

Hier wird dann gesagt:
main.cpp:100: undefined reference to `operator new(unsigned int)'

- woher kommt new?
- die Umgebung weiss vermutlich auch nicht, dass ich C++ nutzen will. 
Also müsste ich wohl noch einen Startupcode haben, der das kann? (und 
dann auch mein new() zur Verfügung stellt?)

von (prx) A. K. (prx)


Lesenswert?

Tobias Plüss schrieb:
> Also müsste ich wohl noch einen Startupcode haben, der das kann?

Ja, der muss die statischen Konstruktoren aufrufen.

> (und dann auch mein new() zur Verfügung stellt?)

Brauchst eine Lib dazu. Beispielsweise die Newlib.

Oder du definierst sie selbst, was nützlich sein kann, wenn du keine 
dynamische Speicherverwaltung im Auge hast und Platz sparen willst.

: Bearbeitet durch User
von Tobias P. (hubertus)


Lesenswert?

Sowas in der Art?
1
void* operator new(size_t size)
2
{
3
  return malloc(size);
4
}
5
6
void operator delete(void *p)
7
{
8
  free(p);
9
}

Die Konstruktoren liegen dann in einer besonderen Sektion des 
Linkerfiles, die ich dann beim Startup Code durchgehen muss und jeden 
Konstruktor aufrufen muss, richtig? Ich denke das könnte man allenfalls 
auch noch herausfinden wie man es machen muss. ;-)

von (prx) A. K. (prx)


Lesenswert?

Tobias Plüss schrieb:
> Die Konstruktoren liegen dann in einer besonderen Sektion des
> Linkerfiles, die ich dann beim Startup Code durchgehen muss und jeden
> Konstruktor aufrufen muss, richtig?

Ja, so in der Art. Da du aber nicht der erste bist, der auf diese Idee 
kommt, könnte eine Suche lohnen. Wobei Linker-Script und Startup-Code 
eine recht innige Ehe führen.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Tobias Plüss schrieb:
> und in meiner main() dann
> test* z;
> z = new test();
Die Frage ist, ob du "new" wirklich verwenden willst. "new" ist ja nur 
sinnvoll, wenn du viele verschiedene Klassen hast, und du zur 
Compile-Zeit nicht entscheiden kannst, von welchen Klassen wie viele 
Instanzen verwendet werden sollen (zB weil du pro Knopfdruck eine neue 
Instanz anlegen willst). Dann musst du die C++ standard Library mit 
linken und malloc() implementieren (wird davon aufgerufen).

Wenn du aber beim Compilieren schon weißt wie viele Instanzen du 
brauchst kannst du auch einfach "test z;" schreiben um eine Instanz, auf 
dem Stack, anzulegen.

von Dr. Sommer (Gast)


Lesenswert?

Tobias Plüss schrieb:
> Die Konstruktoren liegen dann in einer besonderen Sektion des
> Linkerfiles, die ich dann beim Startup Code durchgehen muss und jeden
> Konstruktor aufrufen muss, richtig? Ich denke das könnte man allenfalls
> auch noch herausfinden wie man es machen muss. ;-)
nein, eben nicht! Wenn du "new" und "delete" verwenden willst, werden 
die Konstruktoren direkt von "new" aufgerufen. "new" ist quasi 
malloc()+Konstruktor-Aufruf. Nur wenn du die Objekte global anlegst 
(globale Variablen), müssen die Konstruktoren explizit aufgerufen 
werden; das kannst du durch aufruf von __libc_init_array(); im 
Startup-Code oder am Anfang der main() erreichen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.