Hallo, ich habe ein kleines Problem mit Zugriffen auf Strukturen, Unions und höheren Datentypen. Wie die meisten benutze ich den WinAVR GNU Compiler und die Foldmaster Umgebung zur Erstellung meiner Quellen. Bis jetzt lief auch alles ganz gut. Jedoch bei struct, union o.ä. will der Compiler nicht mehr. Mein Anfang des Programms lautet: int main (void) { struct example { unsigned char test1; unsigned char test2; }; example.test1 = 0x55; * ..... Der Compiler schlägt in der mit * markierten Zeile alarm. Als Rückmeldung bekomme ich lediglich: main.C: In function `int main()': main.C:70: error: parse error before `.' token Exit- Code : 1 ($1) Klingt nach einem Klammerfehler, den ich allerdings nicht erkennen kann. Von mir schon mal Danke im Vorraus Gruß Philipp
Nun, du hast zwar eine struct example deklariert, aber kein einziges Objekt mit dem Namen example selbst.
Hi Jörg, auch wenn ich es mit: ... struct example { unsigned char test1; unsigned char test2; }; example struktur; struktur.test1 = 0x55; ... versuche, klappt es immer noch nicht. Jetzt ist zwar die Übersetzung des C Files fehlerfrei jedoch beim Makefile gibt er nen Fehler. Darunter: class type not supported in coff-ext-avr Liegt es evtl. an Datentypeinstellungen oder so? Gruß
Nu ja, steht doch da. :-) Die Compilierung war fehlerfrei, der Linker auch. Nur die Umwandlung ins AVR-COFF-Format ging nicht. COFF kann kein C++, punkt. Das liegt am Dateiformat, nicht an den Tools. Wenn du AVR-Studio-kompatibel sein willst und C++ haben willst, benutze die neueste Version von AVR Studio zusammen mit ELF+DWARF-2-Debuginfo.
Wobei der Vollständigkeit halber darauf hingewiesen sei, dass WinAVR die Endung mit gross-C als C++ versteht. Nicht jedem Windows-Geschädigten ist das geläufig.
Auf Schlauch steh, :-O Du meinst "ELF+DWARF-2-Debuginfo" als Parameter für den Compileraufruf oder das Makefile (wenn ja wo?). Hab etwas schlechte Erfahrung mit dem Ändern der Makefiles gemacht so das ich nicht gerne darin herumschreibe.
Ich hab jetzt mal im Makefile die Zeile: COFFCONVERT=$(OBJCOPY) --debugging \ mit: COFFCONVERT=$(OBJCOPY) -dwarf-2 \ ersetzt. Nun bekomme ich allerdings weder hex noch symbol files oder des gleichen.
Jetz bin ich verdutzt OO >struct example { > >unsigned char test1; >unsigned char test2; >}; > >example struktur; > >struktur.test1 = 0x55; Das_ lässt sich _so sicher nicht Fehlerfrei Kompilieren! 'example' ist kein Datentyp. Entweder musst Du das so machen: struct example { unsigned char test1; unsigned char test2; }; struct example struktur; struktur.test1 = 0x55; [..] ...oder so: typedef struct example_s { unsigned char test1; unsigned char test2; } example_t; int main(void) { example_t struktur; struktur.test1 = 0x55; return 0; }
"'example' ist kein Datentyp." Doch, wenn er das als C++ übersetzt schon. Und da sein File auf .C endet (statt .c), tut der Compiler das. Unix-Konvention.
Aha, das war mir neu! Das wird wahrscheinlich daran liegen, daß ich so gut wie 0 (NULL) Ahnung von C++ habe... Es wird langsam Zeit :\
@Philipp: Um auf Deinen letzten Beitrag einzugehen: Verwende doch einfach MFile! Da kannst Du das Debugformat ganz bequem per Menü und Mausklick einstellen!
>> Doch, wenn er das als C++ übersetzt schon. > Aha, das war mir neu! Eine struct in C++ ist dasselbe wie eine class, lediglich die initiale Sichtbarkeit der Mitglieder ist `public' bei struct und `private' bei class. Der Rest ist völlig gleich, daher hat er ja im C++-Kontext für die struct auch Debug-Information für eine Klasse erhalten. (`struct' kann auch COFF sehr wohl, ist ja uraltes C. COFF ist bei pre-ANSI stehengeblieben.) Eine Klasse wiederum begründet automatisch einen Typbezeichner ihres Namens (innerhalb des jeweiligen scope bzw. namespace), auch ohne "class" oder "struct" voranzustellen. Gleichfalls übrigens für enum, auch die begründen einen Typnamen. Das sind übrigens einige der kleinen Fallen, warum nicht jedes C89/C99-standardgemäße korrekte C-Programm auch zugleich ein korrektes C++-Programm darstellt. (Andere Fallen sind die reservierten Worte new/delete sowie die Tatsache, dass C nach wie vor old-style function declarations zulässt, während C++ eine leere Parameterliste in der Funktionsdeklaration wie "void" behandelt.)
Hallo Leute, hab jetzt (gestern) bis 3.00 Uhr rumprobiert und das Ergebnis war das mein Makefile so verpfuscht war das ich ein Teil meiner Umgebung wieder neu einrichten musste. Das mfile Tool welches immer wieder erwähnt wird habe ich gar nicht und das Umwandeln der tcl Datei mit Wish84 funktioniert nicht. Kann mir evtl. jemand einmal dieses Tool als WinExe per email zusenden? Vielleicht auch noch eine seiner Makefile Dateien so das ich sie mal mit meiner vergleichen kann wo ich entsprechendes u.U. abändern kann. Gruß Philipp
Ne, also da gibts nix umzuwandeln... Du musst das Ausführen. Bei mir sieht die Verknüpfung so aus: Ziel: C:\WinAVR\bin\wish84.exe mfile.tcl
Ansonsten gibt es auch noch die Option, mal die Suchfunktion Deines Editors im Makefile zu verwenden, und dann nach "DEBUG" zu suchen. Ich finde dann folgendes: Makefile: [..] # Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. # (Note: 3 is not always the best optimization level [..] OPT = s # Debugging format. # Native formats [..] -g are dwarf-2 [default] or stabs. # AVR Studio 4.10 requires dwarf-2. # AVR [Extended] COFF format requires stabs, plus [..] DEBUG = dwarf-2 [..]
So naja, es sieht jetzt so aus: Meine WinAVR Version ist etwas älter (gcc 3.4.3) und die Makefiles die als Beispiel dabei waren hab ich mir etwas abgeändert so das es für mich passt. Allerdings ist der Eintrag DEBUG = .... nicht darin enthalten. Und das Umwandeln der mfile.tcl Datei geht auch nicht. Fehler: % couldn't read file "./htmlview.tcl": no such file or directory Das blöde Ding muss doch zum laufen zu bekommen sein. Gruß
Dann würde ich Dir mal nahelegen, Dein WinAVR auf den aktuellsten Stand zu bringen... Achja, nochmal: es gibt da nichts zum "Umwandeln"...
Und htmlview.tcl ist eine include-Datei, die sollte einfach im gleichen Verzeichnis stehen wie mfile.tcl selbst. Da Windows typischerweise in das Verzeichnis der Applikation hineinwechselt, bevor es sie ausführt, sollte das dann auch gefunden werden.
Nachdem ich nun mehrere Male meine Umgebung neu installiert habe da zwischenzeitlich so viel verstellt das nix mehr ging, bin ich nun an folgender Stelle: Ich habe meine Umgebung wieder auf die alte eingerichtet da ich weiß das die wenigstens geht. Habe den Foldmaster V1.62 und WinAvr V3.4.3 von 2004. Wenn ich nun eine Struktur mit Zugriffen in mein Programm schreibe dann übersetzt er es zwar jedoch ohne die cof files da er diese aus Einstellungsgründen der Datentypen nicht akzeptiert. Nun habe ich zwei Probleme: Wie muss ich mein Makefile (im Anhang enthalten) umschreiben das ich zum AVR Studio kompatibel bin. Wenn das mit dem älteren Compiler überhaupt geht. Und zweitens entstehen beim compilieren fehler in der aktualisierung der Dateien so das mir der Compiler gelegentlich mein Sourcefile mit irgendwelchen Symbolinfos oder des gleichen überschreibt so das mein ganzer Sourcecode vernichtet ist (nur bei main.c der Fall). Würd mich über den ein oder anderen Tipp nochmal freuen.
Ich nochmal, hab jetzt viele meiner Probleme beseitigt aber ein neues. Wenn ich nun mein Makefile aufrufe gibt er die Fehlermeldung: cc1plus.exe: warning: command line option "-std=c89" is valid for C/ObjC but not for C++ aus. Ich hab alle 4 Versionen der Compileroptionen ausprobiert. Aber überall habe ich das selbe Problem.
Gib Deinem Compiler einfach den Schalter -xc, dann hast Du Ruhe vor C++ avr-gcc.exe -xc ... Ich hatte auch mal das Problem, daß C++ das Bit 0 nicht leiden mag und falschen Code erzeugte. Ich benutze auch DOS-Programme und dann werden eben alle Files groß geschrieben. Peter
Ich glaube, Philipp hat gan einfach den Zusammenhang immer noch nicht verstanden. .C, .cxx, .cpp ... das sind alles C++-Files. Er will aber allerhöchstwahrscheinlich gar kein C++ nutzen... Aber davon mal abgesehen: ich habs noch nie geschafft, mir die Build-Umgebung von WinAVR so zu versauen, daß "nichts mehr ging".
Hi, bin en kleinen Schritt weiter, aber immer noch vom Pech verfolgt schrei. Wenn ich meine C Files übersetze klappt jetzt alles. Jedoch wenn ich mein Makefile aufrufe macht er zwar nen hex file und alles ganz gut jedoch ersetzt er in meinem main.C file meinen ganzen C-Code durch ne Art Object oder Symbol Code nach der Art: 6 _tmp_reg_ = 0 7 _zero_reg_ = 1 8 .global __do_copy_data 9 .global __do_clear_bss 17 .Ltext0: 18 .global ucDataSPI 19 .global ucDataSPI 20 .section .bss 23 ucDataSPI: 24 0000 0000 0000 .skip 30,0 24 0000 0000 24 0000 0000 24 0000 0000 24 0000 0000 Liegt das etwa an der Bereinigung oder so?
Philipp, bitte tu dir und uns doch endlich den großen Gefallen, und benenne deine main.C in main.c um (nicht nur im Dateisystem, sondern vor allem im Makefile). Dann wird das Teil wie ganz normales C behandelt und nicht wie C++, außerdem wirst du weiterhin nicht erst noch versuchen, alle Bugs, die das Makefile-Template (und damit auch Mfile) hinsichtlich C++ aufweist, noch einzeln auszuprobieren. GCC und GNU make sind Unix-Tools, da spielen Groß-/Kleinschreibung stets und überall eine Rolle. (Innerhalb von C selbst ja auch.) Wenn du dir einen sauberen Umgang mit der Groß-/Kleinschreibung angewöhnst, hast du nicht nur irgendwann mal selbst weniger Probleme, falls du in die Verlegenheit kommst, auf einem Unix arbeiten zu müssen, sondern dein Projekt wird auch selbst portabel in dieser Hinsicht. Glaub' mir, es ist eine ziemlich ätzende Tätigkeit, in einem schlampig gearbeiteten Projekt das nachträglich alles selbst ändern zu müssen, nur weil man demjenigen helfen will.
"alle Bugs, die das Makefile-Template (und damit auch Mfile) hinsichtlich C++ aufweist, noch einzeln auszuprobieren." Insbesondere die "cleanup" Variante hat einen gewissen Charme - immerhin fegt dabei das Makefile neben allerlei Nebenprodukten vorsorglich den Quelltext gleich mit von der Platte.
Juhu freu hab ne Lösung gefunden. Es geht. Aber warum weiß ich nicht. Zu Jörg: Ich weiß das Anfänger teilweise nerven können (OK meistens) aber bei mir ist es so das ich als Student mich hauptsächlich mit der Hardwareentwicklung beschäftige wie mit dem programmieren. Doch früher oder später muss ich auch mal an den Compiler ran. Und da ich mit Hardwareabläufen und -strukturen besser zu Recht komme hab ichs eben mit der Software etwas schwerer. Ich hab jetzt folgendes gemacht: Habe meine C Sources auf *.c geändert und den Zugriff auf meine Struktur auf: ... struct test { unsigned char test1; unsigned char test2; } example; example.test1 = 0x55; ... abgeändert. Nun ist der Compiliervorgang und das Erstellen der cof Files ohne Fehler. Und jetzt das was ich vor allem dem Jörg noch schulde (und den anderen natürlich auch): Danke!!!! Gruß Philipp Bis zum nächsten Problem ;-)
Ja, genau so. Alternativ zur sofortigen Deklaration einer struct und einer Variablen dieses Typs geht übrigens: struct test { ... }; ... struct test example; Ja, sorry, ich hatte dann natürlich schon wieder vergessen, dass du eher unbewusst ein Feature von C++ benutzt hattest (eine Deklaration von struct test deklariert zugleich einen Typnamen "test", sodass du später "test example;" statt "struct test example;" für die Definition der Variablen schreiben kannst.)
Naja, auch wenn Philipp hier ziemlich resistent die Hinweise ignoriert hat bzw. darauf nicht eingegangen ist und nur durch Zufall eine funktionierende Lösung gefunden hat - ich hab wenigstens in diesem Thread was (technisches) gelernt. Soll heißen eure Müh' war nicht ganz vergebens. :-) Um's gleich vorwegzunehmen: Hätte struct test { unsigned char test1; unsigned char test2; } example; example.test1 = 0x55; nicht auch ohne die ganze Makefileanpassung und Grosskleinschreibungsaktion sofort funktioniert? Ich denke schon. ----, (QuadDash).
Hallo zusammen! Ihr habt ja sowas von Recht. Ich hab mittlerweile zwei Versionen von WinAVR installiert (2004 und 2005). Habe einfach bei einem alten Projekt von mir, welches auf den älteren Compiler zugreift, die Endungen der Dateien von *.C auf *.c geändert und es lief auf anhieb. Kommt das alles nur aus der Verandtschaft zu Unix? Ein Studienkollege sagte mir gestern das fast alles was mit GNU zu tun hat aus der Unix Welt kommt? Egal ob Compiler oder andere Sachen. Die Hauptursache warum mich dieses Problem schon länger verfolgt hat war wahrscheinlich die das Foldmaster wenn ich neue Sourcedateien anlege er sie automatisch mit *.C benennt. Und das die Unterscheidung für den Compiler von C/C++ durch *.c bzw *.C und NICHT durch *.C bzw *.CPP erfolgt wusste ich einfach nicht. Mfg
Warum glaubst Du mir nicht einfach, daß mit -xc alle C++ Probleme gelöst sind ? C++ unterscheidet sich erheblich von C. Mein Problem, daß ich keine Bit0-Portpins nehmen konnte, weil die komplett rausoptimiert wurden war nur durch C++, d.h. durch den fehlenden -xc Schalter entstanden. Warum, wissen die Götter. Peter
> Hätte > struct test { unsigned char test1; > unsigned char test2; > } example; > example.test1 = 0x55; > nicht auch ohne die ganze Makefileanpassung und > Grosskleinschreibungsaktion sofort funktioniert? Nein. Es hätte ihm trotzdem noch regelmäßig seine Datei überbügelt. Wie ich schon schrob: das Makefile-Template ist wirklich nur auf Dateiendungen .c ausgerichtet. In allen anderen Fällen versagt es jämmerlich. > Kommt das alles nur aus der Verandtschaft zu Unix? Ein > Studienkollege sagte mir gestern das fast alles was mit GNU zu tun > hat aus der Unix Welt kommt? Egal ob Compiler oder andere Sachen. Naja: GNU = GNU's not Unix. Es ist also kein Unix. :-) Aber ansonsten ist das schon so, ja, das kommt aus der unixoiden Ecke. Sicher hat aus diesem Grunde C auch (als meiner Erinnerung nach einzige Programmiersprache weit und breit) eine Unterscheidung zwischen Groß- und Kleinschreibung innerhalb der Sprache. > Warum glaubst Du mir nicht einfach, daß mit -xc alle C++ Probleme > gelöst sind ? Weil dem nicht so ist, siehe meine erste Antwort in diesem Block. > C++ unterscheidet sich erheblich von C. So erheblich nun auch wieder nicht. > Mein Problem, daß ich keine Bit0-Portpins nehmen konnte, weil die > komplett rausoptimiert wurden war nur durch C++, d.h. durch den > fehlenden -xc Schalter entstanden. Portzugriffe sollten nie optimiert werden. Du wirst wohl was anderes falsch gemacht haben. Theoretisch sollten sich die C- und C++- Frontends in dieser Hinsicht gar nicht unterscheiden, praktisch aber hat GCC 3.4 aus AVR-Sicht ein paar Eigentümlichkeiten (teilweise auch Rückschritte in der Optimierung im Vergleich zu früheren Versionen), die sich ebenso eigentümlich noch dazu zwischen C und C++ unterscheiden.
@Jörg >> Warum glaubst Du mir nicht einfach, daß mit -xc alle C++ Probleme >> gelöst sind ? > >Weil dem nicht so ist, siehe meine erste Antwort in diesem Block. ??? Er bewirkt also für beliebige Endungen nicht das gleiche, wie ein Sourcefile mit *.c Endung ? Was soll denn diese Schalter anderes machen, als das Sourcefile als reines C-File anzusehen und sämtliches C++ Geraffel abzuschalten ? > Portzugriffe sollten nie optimiert werden. Du wirst wohl was > anderes falsch gemacht haben. Dann erklär mir mal, was man falsch machen kann, damit nur (1<<PIND0) nicht funktioniert, aber alle anderen Bits 1..7 funktionieren, z.B. (1<<PIND2). Es wird natürlich nichts mit C++ im allgemeinen zu tun haben, sondern ein Bug im C++ Geraffel des Compilers sein. Auch ohne C++ ist mir aufgefallen, daß Ausdrücke wie (x&(1<<1)) mit Bitbefehlen optimal ausgewertet werden, aber (x&(1<<0)) nach 16 Bit expandiert und mit 16Bit-ANDierung getestet werden. Aber wenigstens werden sie ja ausgeführt und nicht komplett gestrichen. Codeoverhead ist tolerabel, falscher Code aber nicht ! Ich denke daher, es kann überhaupt nichts schaden, wenn man keinen C++ Code schreibt, das C++ Geraffel auch explizit auszuschalten. Peter
"Was soll denn diese Schalter anderes machen, als das Sourcefile als reines C-File anzusehen und sämtliches C++ Geraffel abzuschalten ?" Der Eigentümlichkeiten des Makefiles wegen. Wie ich schon geschrieben habe - das neigt dazu, den Quelltext wegzuräumen.
> Der Eigentümlichkeiten des Makefiles wegen. Wie ich schon geschrieben > habe - das neigt dazu, den Quelltext wegzuräumen. Na dann ist ja bloß gut, daß ich gar kein Make benutze, sondern meine Batch. Da wird nichts aus heiterem Himmel gelöscht, würde ich mir aber auch stark verbeten haben. Peter
Das wiederum liegt nicht an make selber, sondern am Makefile. Wenn Du ein Batchfile auf C Optimierst und dann einfach davon ausgehst, daß es genauso gut für C++ arbeitet, wirst Du sicherlich auch verdutzt gucken :-)
@OldBug
> Wenn Du ein Batchfile auf C _Optimierst_
Ich habe doch garnichts optimiert.
Ich habe nur den Schalter -xc gegeben und erwarte deshalb daß er jedes
File als pure C ansieht, egal ob es nun *.blabla heißt oder sonstwie.
Und natürlich erwarte ich auch, daß wenn versehentlich Ausdrücke
auftauchen, die zwar unter C++ gültig sind, aber unter pure C ungültig,
daß er mich gehörig anscheißt (Errorreport).
Liege ich nun damit falsch ?
Ich hab Null Ahnung von C++ und wegen dem Bit0-Bug will ich es auch
garnicht.
Peter
Bis jetzt ist der ,,Bit0-Bug'' aber nur eine Behauptung von dir. Solange es dafür keinen fundierten Bugreport (der auch reproduzierbar ist) gibt: sorry. Ansonsten: klar, du kannst auch mit der Technologie von 1970 weiterarbeiten. Der Bug im Makefile liegt nur darin begründet, dass da versucht wird, bestimmte Dinge automatisch aus anderen Dateinamen abzuleiten (z. B. die Namen aller Objektdateien aus den Namen der Eingabedateien, der Name des Listings, auf das viele Leute so stolz sind, aus dem Namen der Eingabedatei, ...) und dass dabei die Endung .c einfach vorausgesetzt wird. Das sind alles Dinge, die du mit einem 08/15-anno-1970-MS-DOS-Batchfile sowieso nicht tun kannst. Ist also ungefähr so, wie dir bei einem Trabanten weder ein Kat noch ein Kühler kaputtgehen konnte. :-) Trotzdem wollen heutzutage nicht mehr sehr viele Leute Trabbi fahren...
Der Bit0 Bug ist mir auch neu. Und ich denke ich hätte es gemerkt, denn da ist bei mir beispielsweise mal der Anschluss vom 1-Wire gelandet - passenderweise mit Peters Code ;-). Aber Bit-Operationen sind beim C Compiler wirklich deutlich effizienter als beim C++-Compiler. Das Backend ist freilich in beiden Fällen identisch. Das C++ Frontend produziert wohl etwas anderem Zwischencode und die Instruction-Templates der entsprechenden Optimierung greifen da nicht.
Komplexe Makefiles sind freilich auch nicht jedermanns Sache. Ich benutze Makefiles schon seit Ewigkeiten und hatte nach entsprechend unangenehmer Erfahrung an der Stelle eine Weile rumgebastelt, aber ohne durchschlagenden Erfolg. Und bin dann bald auf meinen (ur-)alten Bekannten ausgewichen - DMake. Ist vielleicht auch nicht einfacher als GNU-Make, aber den kenne ich halt besser ;-). M.a.W: Jeder mache es so wie er am besten klar kommt. Peters Background ist halt ein gänzlich anderer. Er handelt sich dabei zwar u.U. grössere Compile-Zeiten ein. Aber ehrlich: wieviel Unterschied macht das bei typischen µC-Programmen auf einem 3GHz-Host aus? Apropos 70-er: Diejenigen die auf 70-er Jahre Niveau arbeiten sind wir ;-). Aus der Zeit stammt nämlich der Ur-make. Batch-Dateien hingegen gab es schon in der 50-ern.
> Aber ehrlich: wieviel Unterschied macht das bei typischen > µC-Programmen auf einem 3GHz-Host aus? Bei meinem gegenwärtigen Job 30 Sekunden (gegenüber 3 oder so) auf Linux, noch länger mit dem AVR-GCC auf Windows. Für kleine Änderungen freut man sich da schon, wenn man nicht jedesmal alles übersetzen muss (selbst der Download des Codes in den ATmega128 geht schneller als das Compilieren). > Apropos 70-er: Diejenigen die auf 70-er Jahre Niveau arbeiten sind > wir ;-). Aus der Zeit stammt nämlich der Ur-make. Batch-Dateien > hingegen gab es schon in der 50-ern. :-) Allerdings stammen die benutzten Pattern-Operationen (um deren Probleme es hier ging) wohl eher von Mitte der 90er Jahre.
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.