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 ) { }
Kleine Ergänzung: Das Problem scheint deswegen aufzutreten, weil einer andere Klasse von dieser erbt.
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.
> 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.
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?
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..
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.
> 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.
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.
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.
@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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.