Hallo, ich habe folgendes Problem: Ich nutze AVR-Studio 6 seit einigen Tagen, in Verbindung mit dem AVR Dragon und einem Olimexboard mit dem Mega 16. Nun habe ich eine Routine um Zeitdifferenzen zu berechnen. Dieser Routine werden die Zeitangaben in einer struct übergeben (also ein Pointer darauf). Die Elemente der Struct sind unsigned!. es lässt sich aber einfacher rechnen wenn ich signed Variablen benutze. Deshalb habe ich signed Hilfsvariablen eingeführt: s, h und m. Wenn ich nun den untenstehenden Code debugge, dann springt er mit in die Zeilen ab 6 nicht rein. Er führt 1,2 und 3 durch und springt dann auf Zeile 23. Wenn ich mir s,h und ma anschaue, dann zeigt er mir s und m an, bei h schreibt er "optimized away"... Kann es sein dass der Code wegoptimiert wurde ? Wo stelle ich die Optimierungen ein ? Gruß Karlheinz 1 s = p2->second - p1->second; 2 m = p2->minute - p1->minute; 3 h = p2->hour - p1->hour; 4 5 // Evtl. Korrekturen 6 if (s < 0) 7 { 8 s += 60; 9 --m; 10 } 11 12 if (m < 0) 13 { 14 m += 60;; 15 --h; 16 } 17 18 if (h < 0) 19 { 20 h += 24; 21 flag = 1; 22 } 23 pResult->second = s; 24 pResult->minute = m; 25 pResult->hour = h; 26 if (flag) 27 pResult->day = -1;
unter Project... "<Projektname> Properties Alt+F7" dann unter Compiler / Optimization.
:
Bearbeitet durch User
Gibt's da keinen Meckerer, das "flag" nicht initialisiert ist? Wenn h >= 0?
Das Problem dürfte bereits in der ersten Zeile liegen: die Differenz wird noch als unsigned ausgerechnet, und ist entsprechend immer positiv. Die Bedingung (s<0) ist entsprechend nie erfüllt. Das wird man noch einen expliziten Typecast gebrauchen, etwa: s = (int) (p2->second - p1->second);
Ulrich schrieb: > Das wird man noch > einen expliziten Typecast gebrauchen, etwa: > s = (int) (p2->second - p1->second); dann kann nicht sein. Dieser cast macht kein Sinn weil er zu spät kommt. Wenn überhaupt dann so: s = ( (int)p2->second - p1->second); ich würde aber fast sagen, das es automatisch in int gerechnet wird.
Puh, erstmal Danke für eure Antworten. Jetzt weiß ich wenigstens wo ich die Compilereinstellungen ändern kann und warum das wegoptimiert wird. Das es so ist habe ich im lss-File gesehen, der Assemblercode ist da eindeutig :-) Das casten habe ich aber nicht probiert, ich hatte zwischenzeitlich die Idee dass ganze auf unsigned zu machen, indem ich die Zeitangaben einfach in Sekunden umrechne und das Ergebnis wieder zurückwandle :-) Grrets Karlheinz
Zu früh gefreut. Ich rufe die Funktion mit folgenden Parametern auf: t1->hour: 23, t1->minute: 59, t1->seconds: 32 Für t1 berechnet er das Ergebnis mit 20836, dabei sollte es 86372 sein. Fehler auch bei der Berechnung von t2. Die Optimierungen habe ich alle ausgeschaltet. Wenn ich mit dem Debugger in die Funktion springe, dann sagt ermit zunächst bei t1, t2 und t3: "Optimized ayway". Wenn ich die Berechnung durchgeführt habe, dann steht da ein Ergebnis drin, leider das falsche. Ich habe die t1, t2 und t3 auch schon als static deklariert, bringt aber nichts. unsigned char TimeDiff(KM_DATE_TIME *pResult, KM_DATE_TIME *p1, KM_DATE_TIME *p2) { uint64_t t1,t2,t3; char Overflow=0; char sbuffer[100]; // Zielspeicher loeschen memset(pResult,0,sizeof(KM_DATE_TIME)); // Differenzen auf Sekundenbasis berechnen t1 = 3600 * p1->hour + 60*p1->minute + p1->second; t2 = 3600 * p2->hour + 60*p2->minute + p2->second; if (t1 > t2) { t3 = t1 - t2; Overflow = 1; } else { t3 = t2 - t1; } pResult->hour = t3/3600; t3 -= pResult->hour*3600; pResult->minute = t3/60; t3 -= pResult->minute * 60; pResult->second = t3; sprintf(sbuffer,"TimeDiff: pResult: %d:%d:%d\n\r",pResult->hour, pResult->minute, pResult->second); uart_puts(sbuffer); return Overflow; }
> t1 = 3600 * p1->hour + 60*p1->minute + p1->second;
in C werden Berechnungen in int ausgeführt. Damit bekommt du hier schon
einen überlauf. Du musst die Berechnung schon zwingend mit uint64_t
mache.
t1 = (uint64_t)3600 * p1->hour + 60*p1->minute + p1->second;
müsste für reichen. Aber Sinnvoll finde ich nicht den atmel mit 64bit
Berechnungen zu quälen. Auf einen PC hat 32bit ewig gereicht, warum
brauch du 64bit?
ok, zur Erläuterung habe ich nochmal einen Screenshot als Anhang angefügt. Ich habe jetzt die Variablen außerhalb der Funktion definiert, jetzt werden sie nicht mehr wegoptimiert. Ich berechne zuerst t mit 3600 * p1->hour. pt1->hour; p1->hour hat den Wert 23, t sollte also den Wert 82800 haben. t hat aber nur 17264. Woran kann das liegen ?
Ulrich schrieb: > Das Problem dürfte bereits in der ersten Zeile liegen: die Differenz > wird noch als unsigned ausgerechnet, und ist entsprechend immer positiv. > Die Bedingung (s<0) ist entsprechend nie erfüllt. Doch, denn s ist signed. 100-200 wird also 156 (wenn wir mal mit Bytes rechnen) und das als signed ist -100. Peter II schrieb: > Ulrich schrieb: >> Das wird man noch einen expliziten Typecast gebrauchen, etwa: >> s = (int) (p2->second - p1->second); > > dann kann nicht sein. Dieser cast macht kein Sinn weil er zu spät kommt. Nein, tut er nicht (zumindest für diese Rechnung, s.o. > Wenn überhaupt dann so: > > s = ( (int)p2->second - p1->second); Dann wird duie rechnung aber als unsigned ausgeführt, weil p1->second unsigned ist. Aber wie gesagt änder das nix am Ergebnis.
Update: SO funktioniert es, ich kann mir nur nicht erklären warum .....
Karlheinz Druschel schrieb: > SO funktioniert es, ich kann mir nur nicht erklären warum ..... habe ich doch geschrieben, die Berechnung wird mit int gemacht. Damit bekommst du einen Overflow. Wenn alles Variablen 64bit sind, wird auch mit 64bit rechnet. - aber schön ist anders.
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.