Forum: Compiler & IDEs ARM GCC mit C++


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tobias P. (hubertus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.