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.