Forum: Compiler & IDEs Warning bei avr-g++


von Ingo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich entwickle gerade ein Programm für den ATMega168 mit avr-g++ (also
C++ Code). Da bekomme ich bei zwei Klassen folgende Fehlermeldung

grabberBase.h:20: warning: alignment of
'GrabberBase::_ZTV11GrabberBase' is greater than maximum object file
alignment.  Using 1

Der Compileraufruf ist:
avr-g++  -mmcu=atmega168 -Wall -gdwarf-2  -DF_CPU=18432000  -O2
-fsigned-char -Wp,-M,-MP,-MT,grabberBase.o,-MF,dep/grabberBase.o.d  -c
grabberBase.c

Das C-File kann ich leider nicht attachen deswegen die paar Zeilen am
Ende des Textes plain.

#include <avr/io.h>
#include <avr/delay.h>

#include "hardwaredescription.h"
#include "grabberBase.h"
#include "retina.h"

GrabberBase::GrabberBase( void )
{
}


GrabberBase::GrabberBase( RetinaParams & retinaParams ) : _retina(
retinaParams )
{
  init( retinaParams );
}

void GrabberBase::init( RetinaParams & retinaParams )
{
  // Initialise the retina chip
  _retina.init( retinaParams );
}

void GrabberBase::grabImage( void )
{
}

von Ingo (Gast)


Lesenswert?

Kleine Ergänzung: Das Problem scheint deswegen aufzutreten, weil einer
andere Klasse von dieser erbt.

von Ingo (Gast)


Angehängte Dateien:

Lesenswert?

OK, die Ursache scheint virtuelle Vererbung zu sein. Der attachte code
compiliert ohne Probleme, wenn man die Methode test nicht virtuell
deklariert. Sobald sie virtuell deklariert ist, klappt's nicht mehr
und die Warning erscheint.

von Rolf Magnus (Gast)


Lesenswert?

> OK, die Ursache scheint virtuelle Vererbung zu sein.

Das ist keine virtuelle Vererbung, sondern polymorphie.

> Der attachte code compiliert ohne Probleme, wenn man die Methode
> test nicht virtuell deklariert. Sobald sie virtuell deklariert
> ist, klappt's nicht mehr und die Warning erscheint.

Was heißt "klappt's nicht mehr"? Funktioniert der Code dann auch
nicht? Ich weiß zwar nicht so genau, was die Warnung sagen will, aber
sie scheint mir eher harmlos zu sein, da alginment auf dem AVR eh kein
Thema ist.

von Ingo (Gast)


Lesenswert?

Du hast natürlich recht, es ist Polymorphie.

Der Test-Code funktioniert im Simulator anscheinend. Da ich die warning
aber nicht interpretieren kann bin ich etwas beunruhigt. Den Code für
die Klasse bei der die warning zuerst aufgetaucht ist kann ich nicht
testen, da die Hardware noch nicht fertig ist.

Weiss denn jemand, was mit 'object file alignment' gemeint ist?

von AvrNewbie (Gast)


Lesenswert?

Hallo Ingo,
leider hast du ja nicht den ganzen Source code gepostet, deshalb kann
ich höchstens mal raten.
Ich hatte schon mal ein ähnliches Problem, allerdings war die
Fehlermeldung etwas anders und das ganze war auf nem PowerPC.

Spontan würden mir zwei Fehlerursachen einfallen:
1.) Du hast in deiner Klasse nen grosses Array (> ca. 32k) angelegt,
oder irgendwie sonst ne Menge Speicher mit dem Objekt belegt, so das
die  object size grösser als 32k is. Dann wird aber nur bei virtueller
Vererbung ne Warning ausgegeben (deshalb könnte das hier vielleicht
passen, eventuell is die max. object size auch kleiner wie 32k)

2.) Irgendwie ist der Atmel, oder g++ doch vom alignment abhängig. Das
der Fehler auch in diesem Fall nur dann auftritt, wenn es eine
virtuelle Basisklasse ist liegt daran, das eine virtuelle Basisklasse
immer am Ende eines Objekts angehängt wird und nicht am Anfang, wie bei
normaler Vererbung.

Leider kann ich dir nicht genau sagen, wie man das bei nem Atmel dann
beheben..

von Ingo (Gast)


Lesenswert?

Update bis jetzt:

Ich habe mir den Assembler-Code angeschaut und Jörg Wunsch hat auf mein
Crossposting (ja ich weiß, pfui über mich) bei avrfreaks den guten
Hinweis, auf das .valign Keyword gegeben.

Das ist es zwar nicht, war aber ein Ansatz in die Beschreibung des GCC
hineinzuschauen. Der Assemblercode sieht sauber aus. Der gcc scheint
beim Erzeugen der Virtual Function Table diese auf ein bestimmte
alignment (ich vermute mal 4, sprich 32bit Grenze) ausrichten zu
wollen, was beim AVR aber nicht nötig ist und deswegen auf 1 (Object
file alignment) gesetzt wird.

Der Code funktioniert im Simulator auch wie erwartet, Hardwaretests
stehen aber noch aus. Sobald ich mehr weiss, werde ich die Erkenntnisse
hier kundtun.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Der gcc scheint beim Erzeugen der Virtual Function Table diese auf
> ein bestimmte alignment (ich vermute mal 4, sprich 32bit Grenze)
> ausrichten zu wollen, was beim AVR aber nicht nötig ist und deswegen
> auf 1 (Object file alignment) gesetzt wird.

Ja, aber genau dafür braucht's IMHO entweder ein .valign, oder aber
die vtable geht in eine eigene Section und diese hat ein Alignment.
Das müsste aber aus dem generierten Assemblercode ersichtlich sein.

von Ingo (Gast)


Angehängte Dateien:

Lesenswert?

Hi Jörg,

also im assembler-code (attached) finde ich nichts dergleichen. Wie
gesagt: Da das Problem nur bei Polymorphie auftritt, unabhängig
davon, ob eine Klasse von einer anderen erbt oder nicht, bleibt als
einzige Erklärung nur die Virtual Function Table.

Wenn ich die Dokumentation des gcc richtig verstanden habe, kann man,
wenn der Compiler gebaut wird, verschiedenste Alignments angeben (z.B.
für structs, char, int, float, object file, ...). Es ist allerdings
nicht beschrieben, wie die Rangfolge der Alignments aussieht. Daher
meine Vermutung, dass das Alignment für die vtable vom object file
alignment ausser Kraft gesetzt wird. Darüber informiert der gcc dann
mit der warning.

Einige newspostings von älteren gcc-ports für andere Plattformen
schildern ähnliche Effekte, dort ist es aber zu Problemen mit dem
erzeugten Code gekommen, was beim avr-g++ aber nicht der Fall zu sein
scheint. Aber richtig beruhigt bin ich erst, wenn ich dass auf Hardware
verifiziert habe.

von Rolf Magnus (Gast)


Lesenswert?

Was mich ja auch noch stört, ist, daß die vtable im RAM abgelegt wird.
Das ist bei AVRs ja doch recht knapp, und da die vtable sich eh nicht
ändert, wäre es schöner, wenn sie direkt aus dem Flash heraus verwendet
würde.
Da mein aktuelles Projekt einen großen Teil des RAM braucht, ist das
für mich momentan das Argument gegen den Einsatz virtueller Funktionen.

von Ingo (Gast)


Lesenswert?

@Rolf: Ja, das ist in der Tat nicht so schön. Die Alternative wären in
meinem Fall callbacks in der Art einer "virutellen Polymorphie" :-)
oder eine Auswahl der Klassen durch #ifdefs. Bei ersterem ist dann eben
mehr Code im Flash (für das registrieren der callbacks und zwei Byte für
den function pointer im RAM) aber man kommt ohne vtable aus. Zweiteres
möchte ich vermeiden, da der Code dann für meinen Geschmack
unübersichtlich und schlecht wartbar wird.

Da meine Zielapplikation im Moment aber mit 56Byte RAM einschließlich
vtable (12Byte) auf einem Mega168 auskommt, ist das bei mir nicht so
kritisch.

von Ingo (Gast)


Lesenswert?

Es funktioniert auch in Hardware.

Da das debuggen mit dem AVR-Studio aber mit C++ (noch) nicht klappt,
bleibe ich erst mal bei C.

Interessanter Nebeneffekt. Der C++ Code benötigt zwar etwas mehr Flash
aber weniger RAM bei sonst gleicher Funktionalität. Ich nehme an (habe
das aber nicht im Detail geprüft), dass der Optimizer bei Klassen
besser mit den Registern hantiert als bei reinem C-Code.

Insgesamt bin ich aber mit beiden sehr zufrieden. Die Möglichkeit den
Code im AVR Studio debuggen zu können hat bei mir letztendlich den
Ausschlag gegeben C zu nutzen.

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.