Wenn ich in meinem Code eine Variable als unsigned int oder uint8_t definieren bekomme ich bei jeder for-funktion immer folgende Fehlermeldung: warning: comparsion is always true due to limited range of data types Meine for-funktion sieht folgendermaßen aus: for (t=wait;t>=0;t--) { //führe code in for-schleife aus } Irgendjemand eine Idee woran das liegen kann?
Eine Variable vom Typ "unsigned irgendwas" kann nicht negativ werden. Der Vergleich variable >= 0 ist somit immer wahr.
"Irgendjemand eine Idee woran das liegen kann?" Geh nochmal zurück in die erste Klasse: Natürliche Zahlen (unsigned) sind immer >= 0. Peter
Upps, mein Fehler ! Aber so müsste es doch gehen. Zumindest bekomme ich keine Fehlermeldung mehr. for (t=wait;t|=0;t--) { //führe code in for-schleife aus }
...vermutlich willst Du das: for(t = wait; t > 0; t--); { /* code... */ } ?
> Aber so müsste es doch gehen.
Ob das so geht kannst du in wenigen Minuten selbst, evlt. mit Hilfe
eines Debuggers, herausfinden.
Interessanterweise sollte das tatsächlich funktionieren, wenn auch eine
unübliche Lösung. Aber bitte tu dir den Gefallen und lies das Kapitel
über for-Schleifen und das über Vergleichsoperatoren in deinem C-Buch
nochmal genau durch, damit du verstehst, wieso das funktioniert. :)
for(t = wait; t; t--); { /* code... */ } ist Code-sparender als z.B. for(t = 0; t < wait; t++); { /* code... */ } und somit schon üblich.
SORRY!! Ohne die ";" SCH... Kopiererei. for(t = wait; t; t--) { /* code... */ } ist Code-sparender als z.B. for(t = 0; t < wait; t++) { /* code... */ } und somit schon üblich.
> und somit schon üblich. Auf diese Weise natürlich (wobei ich vermutlich "t != 0" in die Bedingung schreiben würde, für den Compiler ist das das gleiche). Aber schau dir nochmal genau die Version von Tobias an: > for (t=wait;t|=0;t--) Du wirst wohl nicht bestreiten, dass "t |= 0" als Bedingung ein wenig unüblich und nicht gerade sehr intuitiv ist.
Oh, t|=0 als Bedingung geht zwar ist aber schon seltsam. Ich hab wohl t!=0 gelesen....
Also ist wohl: for(t = 0 ; t < wait ; t++) { } die Lösung, die am Besten ist und am wenigsten Speicher benötigt. Oder ?
Nein, Tobis Variante ist potentiell platzsparender: for(t = wait; t; t--) { /* code... */ } Ein Test auf 0 ist je nach Architektur schneller als ein Test auf einen bestimmten Wert. Allerdings bezweifle ich beinahe, dass das im fertigen Programm signifikante (=messbare) Auswirkungen hat.
Nachtrag: Die Schleifen unterscheiden sich allerdings ein wenig, abgesehen von der Laufrichtung. Bei deiner Variante nimmt t niemals den Wert wait an, dafür ist es beim ersten Durchlauf 0. Bei der platzsparenderen Variante wird t niemals 0 und ist beim ersten Durchlauf gleich wait.
Also welche Variante ist jetzt potentiell besser ? for(t = wait; t; t--) { } oder: for(t = 0 ; t < wait ; t++) { }
Zyklen zählen darfst Du selber ;) --8<-- for (t = wait; t; t--) d2: 80 91 00 01 lds r24, 0x0100 d6: 90 91 01 01 lds r25, 0x0101 da: 90 93 03 01 sts 0x0103, r25 de: 80 93 02 01 sts 0x0102, r24 e2: 80 91 02 01 lds r24, 0x0102 e6: 90 91 03 01 lds r25, 0x0103 ea: 89 2b or r24, r25 ec: 31 f0 breq .+12 ; 0xfa ee: 80 91 02 01 lds r24, 0x0102 f2: 90 91 03 01 lds r25, 0x0103 f6: 01 97 sbiw r24, 0x01 ; 1 f8: f0 cf rjmp .-32 ; 0xda ; for (t = 0; t <= wait; t++) fa: 10 92 03 01 sts 0x0103, r1 fe: 10 92 02 01 sts 0x0102, r1 102: 20 91 02 01 lds r18, 0x0102 106: 30 91 03 01 lds r19, 0x0103 10a: 80 91 00 01 lds r24, 0x0100 10e: 90 91 01 01 lds r25, 0x0101 112: 82 17 cp r24, r18 114: 93 07 cpc r25, r19 116: 50 f0 brcs .+20 ; 0x12c 118: 80 91 02 01 lds r24, 0x0102 11c: 90 91 03 01 lds r25, 0x0103 120: 01 96 adiw r24, 0x01 ; 1 122: 90 93 03 01 sts 0x0103, r25 126: 80 93 02 01 sts 0x0102, r24 12a: eb cf rjmp .-42 ; 0x102 ; -->8--
t ist uint8_t Steht aber auch ganz am Anfang. Von Assembler hab ich keine Ahnung, deswegen weiß ich auch nicht was ich dort zählen soll.
Ich habe sicherheitshalber nachgefragt, denn: Ist 't' nur uint8_t, dann kannst Du Dir die ganze for-Schleife sparen, die wird ziemlich sicher wegoptimiert. Der Code, der in der Schleife ausgeführt wird könnte noch Einfluss darauf haben, aber das ist nach Deinen bisherigen Auskünften unwahrscheinlich. Wenn Du wissen willst, welche Variante performanter ist, dann musst Du Dich schon damit auseinandersetzen, wie viele Zyklen die jeweiligen Assembleranweisungen zur Ausführung benötigen. Ich bin da grad zu faul zu...
Probiers mal aus! Kompilier beide Varianten und schau nach, wieviel Code rauskommt. Das steht im Output Fenster unten am Bildschirm, wenn du im Programers' Notepad programmierst: Device: atmega32 Program: 10464 bytes (31.9% Full) (.text + .data + .bootloader) Data: 324 bytes (15.8% Full) (.data + .bss + .noinit) c:\avr\atmega_projects\mainboard_tester>pause Drcken Sie eine beliebige Taste . . .
Habs mal gerade ausprobiert: for (t=x;t;t--) AVR Memory Usage: Device: at90s2323 Program: 1362 bytes (66.5% Full) (.text + .data + .bootloader) Data: 0 bytes (0.0% Full) (.data + .bss + .noinit) for (t=0;t<=x;t++) AVR Memory Usage: Device: at90s2323 Program: 1422 bytes (69.4% Full) (.text + .data + .bootloader) Data: 0 bytes (0.0% Full) (.data + .bss + .noinit)
"Also welche Variante ist jetzt potentiell besser ?" Im Prinzip stimmen die Kommentare oben zwar schon, aber es hängt auch arg vom Compiler ab. Wenn t in der Schleife nicht verwendet wird, dann ist beispielsweise bei GCC der Code der Schleife identisch. Weil der diese klassische Kontrollstruktur identifiziert und optimiert: .L5: ..for-body.. sbiw r28,1 brne .L5 Und wenn's drauf ankommt: Gilt wait > 0, dann ist t = wait; do ... while (--t != 0); etwas kürzer als jede for-Variante.
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.