Für dieses Forum muß Javascript im Browser aktiviert werden!
Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C2 Quellcode formatieren: <code>Quellcode</code> ASM Quellcode formatieren: <asm>Quellcode</asm> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! > Hallo Sebastian, > > Dieses Problem liegt nicht an der CC2 selbst, sondern ist ein Compiler-Fehler. > Du bist scheinbar als erstes darüber gestolpert. > Um einmal zu erklären, was passiert: > Der Compiler besitzt eine Optimierung, um Berechnungen konstanter Ausdrücke > bereits beim Kompilieren auszuführen. > Aus > <code> x= a+(5-2)*3;</code> > wird folgendes kompiliert: > <code> x= a+9;</code> > Hierbei wird auch das überschreiten des Wertebereichs eines Datentyps berücksichtigt. > (z.B. Integer zu Long) > > Nun muß man ein paar Dinge zu eigenen Datentypen wissen, um zu verstehen, > was diese Optimierung mit eigenen Datentypen zu tun hat. > Eigene Datentypen werden intern als einfache Datenarrays behandelt. > Der Index wird in Deinem Fall aus den drei Parametern und anhand der Größe > jeder Elementdimension berechnet. > > In Deinem Fall hat dieses Array 40320 Byte. > Und genau hier liegt der Knackpunkt. > Greift man nun auf mittels konstanter Parameter, hier <code> test.x[60].y[15].z[4].a </code>, > zu, dann versucht der Compiler diese drei Zahlen schon wärend dem Kompilieren > zu berechnen und einen konstanten Ausdruck daraus zu erstellen. > Und hier kommen wir bereits zum Problem. > Das (Byte-)Index auf diese Variable ist über 32767, und somit außerhalb des Integerbereichs. > Der Index ist nämlich 39032. Hier wechselt der Compiler den Wertbereich auf Longinteger. > Longinteger-Konstanten werden nicht wie Byte-und Integer-Konstanten im VM-Code eingebettet, > sondern im Konstantenspeicher abgelegt. > Und genau bei der Abfrage dieser Konstante passiert beim Kompilieren ein Fehler: > <code>thread main > { > test.x[60].y[15].z[4].a = 1; > } > > 324 : VM_LOAD_IMMEDIATE_BYTE 1 > 134 20 : VM_LOAD_IMMEDIATE_INT 20 > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 69 : VM_ADD CALC_INT_INT > 137 5 : VM_LOAD_CONST_LONG 5 > 325 : VM_ADD CALC_INT_LONG > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 837 : VM_ADD CALC_LONG_INT > 134 600 : VM_LOAD_IMMEDIATE_INT 60 > 837 : VM_ADD CALC_LONG_INT > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 837 : VM_ADD CALC_LONG_INT > 8260 : VM_LOAD_IMMEDIATE_BYTE 20 > 837 : VM_ADD CALC_LONG_INT > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 837 : VM_ADD CALC_LONG_INT > 21 : VM_STORE_REF_INT > 132 65514 : VM_BRANCH -22 > 65535 65535 65535 65535 65535 65535 65535 65535 65535 65535 > </code> > > Im Stack steht ein Long-Wert(32-Bit). Der VM-Code VM_STORE_REF_INT erwartet aber > einen 16Bit-Wert im Stack. > Und genau hier passiert ein Neustart, da das OS völlig korrekt dies als Fehler > ansieht und das Programm neu startet. > Das ist eine Sicherheitsmaßnahme im OS, <b>bevor</b> die CC2 infolge > eines Fehlers im Kompilat verrücktspielen kann. > > Allerdings kenne ich keine Anwendung, bei der dieses Problem wirklich ein Problem ist. > Denn, man greift auf Arrays, besonders auf eigene Datentypen, normalerweise nicht > mit Konstanten Ausdrücken zu, sondern mit Variablen. > Denn dann tritt dieses Problem nicht auf. > > Gibt man z.B. für die oberste Ebene Deines Datentyps eine Variable, und keine > Konstante an, besteht das Problem nicht mehr, da der Wertebereich Integer bleibt: > <code>byte i; > thread main > { > i=60; > test.x[i].y[15].z[4].a = 1; > } > 15428 : VM_LOAD_IMMEDIATE_BYTE 60 > 147 40340 : VM_STORE_BYTE 40340 > 324 : VM_LOAD_IMMEDIATE_BYTE 1 > 134 20 : VM_LOAD_IMMEDIATE_INT 20 > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 69 : VM_ADD CALC_INT_INT > 139 40340 : VM_LOAD_BYTE 40340 > 134 640 : VM_LOAD_IMMEDIATE_INT 640 > 71 : VM_MUL > 69 : VM_ADD CALC_INT_INT > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 69 : VM_ADD CALC_INT_INT > 134 600 : VM_LOAD_IMMEDIATE_INT 600 > 69 : VM_ADD CALC_INT_INT > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 69 : VM_ADD CALC_INT_INT > 8260 : VM_LOAD_IMMEDIATE_BYTE 0 > 69 : VM_ADD CALC_INT_INT > 68 : VM_LOAD_IMMEDIATE_BYTE 0 > 69 : VM_ADD CALC_INT_INT > 21 : VM_STORE_REF_INT > 132 65508 : VM_BRANCH -28 > 65535 65535 65535 65535 > </code> > Der Compiler optimiert zwar noch die 15 und die 4 zu einem Offset von 600, > aber der Rest wird zur Laufzeit berechnet. (60*640) > > Ich glaube, so sollte es klar sein, was hier passiert. > > > Noch eine Anmerkung zur Setzung von Klammern: > Ich weiß, daß es in C üblich ist, die geschweiften Klammern so zu plazieren, wie Du es machst, > jedoch ist es extrem unübersichtlich. Besser ist es, die Klammern immer in > dieselbe Ebene zu setzen: > <code>thread xy > { > loop > { > if <Bedingung> > { > //... > } > else > { > //... > } > while <Bedingung> > { > //... > } > } > } > </code> > Auf diese Weise können auch andere den Quelltext leichter lesen. > > > MfG André H. > > > > Hi, > > > > ich benutze folgende datenstruktur: > > > > <code> > > type t4{ > > int a; > > int b; > > int c; > > int d; > > } > > type t3{ t4 z[5]; } > > type t2{ t3 y[16];} > > type t1{ t2 x[63];} > > </code> > > > > sie belegt 40320 byte. (63*16*5*4*2) > > das sagt auch die c2p.vmc: > > > > <code> > > CC2VMC > > 64 > > 240 > > > > 1 0 0 0 148 157 148 157 > > </code> > > > > ich habe 128kb für das programm, es sollte also genug platz sein. > > Wenn ich aber in den oberen bereich (ab etwa t2[55]) daten ungleich 0 schreibe, spielt die CC2 verrückt. > > > > woran liegt das? > > > > hier ein komplettes programm zum testen: > > bei mir ist dauernd der piezo zu hören, denke die cc2 bootet dauernd neu ... > > > > <code> > > type t4{ > > > > int a; > > int b; > > int c; > > int d; > > > > } > > > > type t3{ > > t4 z[5]; > > } > > > > > > type t2{ > > t3 y[16]; > > } > > > > type t1{ > > t2 x[63]; > > } > > > > t1 test; > > > > > > thread main{ > > > > test.x[0].y[0].z[0].a = 1; > > test.x[50].y[0].z[0].a = 1; > > test.x[60].y[15].z[4].a = 1; > > > > } > > </code> > > > > > >