www.mikrocontroller.net

Forum: Compiler & IDEs for-Funktion Datentypen


Autor: Tobias P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Variable vom Typ "unsigned irgendwas" kann nicht negativ werden.
Der Vergleich

   variable >= 0

ist somit immer wahr.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Irgendjemand eine Idee woran das liegen kann?"

Geh nochmal zurück in die erste Klasse:

Natürliche Zahlen (unsigned) sind immer >= 0.


Peter

Autor: Tobias P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
}

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...vermutlich willst Du das:

for(t = wait; t > 0; t--);
{
  /* code... */
}

?

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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. :)

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
for(t = wait; t; t--);
{
  /* code... */
}

ist Code-sparender als z.B.

for(t = 0; t < wait; t++);
{
  /* code... */
}

und somit schon üblich.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, t|=0 als Bedingung geht zwar ist aber schon seltsam.
Ich hab wohl t!=0 gelesen....

Autor: Tobias P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ist wohl:

for(t = 0 ; t < wait ; t++)
{
}

die Lösung, die am Besten ist und am wenigsten Speicher benötigt.
Oder ?

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Tobias P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also welche Variante ist jetzt potentiell besser ?


for(t = wait; t; t--)
{
}

oder:

for(t = 0 ; t < wait ; t++)
{
}

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal so ganz nebenbei: wie ist 't' definiert?

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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--

Autor: Tobias P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
Drcken Sie eine beliebige Taste . . .

Autor: Tobias P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.