Forum: Mikrocontroller und Digitale Elektronik Atmel Studio 7 Bug? Bei For-Schleife und == Abfrage


von Malte H. (avr_alvarr)


Lesenswert?

Hallo erstmal,

ich habe mich schon des oefteren hier im Forum bei Problemen informiert 
und bin bis jetzt auch immer fuendig geworden.

Jedoch bin ich jetzt auf eine Eigenart in Atmel Studio gestossen, welche 
fuer mich keinen Sinn ergibt.

Zu meiner Person sei noch gesagt, dass ich das Programmieren lediglich 
als Hobby ausuebe und die Kenntnisse auf einem mittel-niedrig Level 
sind, da ich erst vor ein paar Monaten von Basic auf C gewechselt habe.

Nun zu meinem Problem:

Wenn ich folgenden Code Compilieren moechte, dann funktioniert das zwar, 
was aber auffaellig ist, sind folgende Daten aus dem Output:
(Und das Programm funktioniert auch nicht)

Program Memory Usage   :  130 bytes
Data Memory Usage   :  0 bytes

Aendere ich jetzt jedoch (i=0; i==18; i++) in (i=0; i<18; i++), dann 
zeigt mir der Output folgendes an und das Programm funktioniert wie 
erwartet:

Program Memory Usage   :  424 bytes
Data Memory Usage   :  144 bytes

Der Code ist erst mal nur ein Test zum Testen der Hardware: (F_CPU ist 
mit 16MHz in den Symbols angegeben)
1
#include <util/delay.h>
2
#include <avr/io.h>
3
#include <stdio.h>
4
#include <avr/interrupt.h>
5
#include "light_ws2812.h"
6
#include "LightDefs.h"
7
8
struct cRGBW led[36];
9
10
int main(void)
11
{
12
  int i;
13
  while(1)
14
  {
15
    for (i=0; i==18; i++)
16
    {
17
      led[i].r=0;led[i].g=20;led[i].b=0;led[i].w=0;   
18
      if (i>0) {led[(i-1)].r=0;led[(i-1)].g=0;led[(i-1)].b=0;led[(i-1)].w=0;}    
19
      led[(i+18)].r=0;led[(i+18)].g=20;led[(i+18)].b=0;led[(i+18)].w=0;  
20
      led[(i+17)].r=0;led[(i+17)].g=0;led[(i+17)].b=0;led[(i+17)].w=0;    
21
      ws2812_setleds_rgbw(led,36);
22
      _delay_ms(50);  
23
    }
24
  }
25
}

Natuerlich sollte man sowieso mit <> abfragen, jedoch kann es doch mal 
vorkommen, dass man mit == abfragen kann oder stehe ich jetzt total auf 
dem Schlauch?

Auf jeden Fall bedanke ich mich schon mal fuer`s durchlesen meines 
Problems und lasse mich gerne eines Besseren belehren ;)

Malte

: Bearbeitet durch User
von Daniel F. (df311)


Lesenswert?

der 2 parameter in for ist die fortsetzungsbedingung (solange erfüllt 
mach)
d.h. bei i=0 als start ist die bedingung i==18 nicht erfüllt, daher wird 
die schleife nie ausgefürt.

p.s. <> ist in c !=

: Bearbeitet durch User
von Conny G. (conny_g)


Lesenswert?

Der 2. Parameter der for Schleife ist die Durchlaufbedingung, d.h. die 
Schleife wird nur ausgeführt wenn true.
Der Compiler stellt fest, dass der Startwert bereits nicht der 
Durchlaufbedingung genügt und optimiert die ganze Schleife weg.

von Adam P. (adamap)


Lesenswert?

Du sagst dem Compiler folgendes:
1. i ist 0
2. solange i gleich 18 ist, verarbeite und erhöhe i

...Dies trifft NIE zu, da i am Anfang 0 ist und somit ist die Bedingung 
nicht erfüllt, es wird "entfernt".

von Andy (Gast)


Lesenswert?

du hast die for-Schleife bzw. deren Bedingungen nicht richtig 
interpretiert.
es Heißt wörtlich:
Starte mit "i gleich 0",wiederhole so lange "i gleich 18" ist und 
"erhöhe i um 1" nach jeder Runde.
Macht so keinen Sinn, gell ;)

von 50c (Gast)


Lesenswert?

Malte H. schrieb:
> for (i=0; i==18; i++)

..."übersetzt" heißt das, der mittlere Part des for, solange wie i 
gleich 18 ist.

...und der Compiler merkt, dass dies nie sein wird und optimiert das 
gesamte for einfach mal weg...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Irgendwie verstehe ich dich nicht ganz: Du änderst in deinem Code die
Bedingung i<18 in i==18, was logischerweise ein völlig anderes Verhalten
des Programms bewirken muss, und wunderst dich darüber so sehr, dass du
gleich einen Bug in den Entwicklungstools vermutest?

von Malte H. (avr_alvarr)


Lesenswert?

Wow, seid ihr schnell!!!

Ist ja schon ein bisschen peinlich jetzt fuer mich...

Aber nun gut. Hab wirklich komplett falsch "Gedacht" bei dem zweiten 
Parameter...

Jetzt macht das Alles einen Sinn ;)

Vielen lieben Dank fuer eure freundlichen und aufklaerenden Antworten.

Das zeigt mir, dass ich nach einem Jahrzent vb-fun.de fuer Basic jetzt 
ein neues super C Forum gefunden habe.

Wuensche euch allen noch einen schoenen Tag.

Gruss,

Malte

von Malte H. (avr_alvarr)


Lesenswert?

Hab den 2. Parameter komplett missverstanden.
Ich dachte (warum auch immer), dass die Schleife ausgefuehrt wird, bis 
der Wert im zweiten Parameter erreicht wird...
Aber nun gut. Ab in die Ecke der Schande mit mir ;)

von Jim M. (turboj)


Lesenswert?

Malte H. schrieb:
> Ich dachte (warum auch immer), dass die Schleife ausgefuehrt wird, bis
> der Wert im zweiten Parameter erreicht wird...

Dann besorge Dir mal ein richtiges Buch über die Programmmiersprache C, 
z.B. den K&R.

Die ist nämlich ohne zusätzliche Literatur relativ schlecht 
verständlich, und hat viele fiese Fußangeln für Anfänger.

von Sebastian S. (amateur)


Lesenswert?

Langer Rede kurzer Sinn:
Der Compiler macht, was Du ihm sagst – und nicht was Du meinst.

Ob der, der an der Tastatur sitzt, weiß was er sagt, ist etwas anderes.

Natürlich sind immer die anderen schuld.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Außerdem rate ich Dir die Nutzung von Leerzeichen vor und hinter 
Operatoren und den Beginn einer neuen Zeile nach einem Semikolon (außer 
bei for()).

Das hier
1
      led[i].r=0;led[i].g=20;led[i].b=0;led[i].w=0;   
2
      if (i>0) {led[(i-1)].r=0;led[(i-1)].g=0;led[(i-1)].b=0;led[(i-1)].w=0;}    
3
      led[(i+18)].r=0;led[(i+18)].g=20;led[(i+18)].b=0;led[(i+18)].w=0;  
4
      led[(i+17)].r=0;led[(i+17)].g=0;led[(i+17)].b=0;led[(i+17)].w=0;    
5
      ws2812_setleds_rgbw(led,36);

kann man nicht lesen - jedenfalls nicht, ohne Kopfschmerzen zu bekommen. 
Tippfehler (Vertauschung von g und b) kann man in diesem Salat nicht 
mehr erkennen.

Ich habe den Code mal aufgedröselt.
Das hier:
1
    led[i].r = 0;
2
    led[i].g = 20;
3
    led[i].b = 0;
4
    led[i].w = 0;
5
6
    if (i > 0)
7
    {
8
        led[(i - 1)].r = 0;
9
        led[(i - 1)].g = 0;
10
        led[(i - 1)].b = 0;
11
        led[(i - 1)].w = 0;
12
    }
13
14
    led[(i + 18)].r = 0;
15
    led[(i + 18)].g = 20;
16
    led[(i + 18)].b = 0;
17
    led[(i + 18)].w = 0;
18
19
    led[(i + 17)].r = 0;
20
    led[(i + 17)].g = 0;
21
    led[(i + 17)].b = 0;
22
    led[(i + 17)].w = 0;
23
24
    ws2812_setleds_rgbw(led, 36);

ist da wesentlich "wartungsfreundlicher".

: Bearbeitet durch Moderator
von Malte H. (avr_alvarr)


Lesenswert?

@Jim Meba

hab ich gestern Abend noch gekauft ;)
Sie hatten bei uns, wie es der Zufall so will, "AVR Mikrocontroller - 
Programmierung in C von Heimo Gaicher" auf Lager gehabt. Und da habe ich 
es gleich mal mitgenommen...


@Frank M

Vielen Dank fuer deinen Hindweis und den wartungsfreundlicheren Code :)
Das werde ich mir dann gleich so angewoehnen.
Klar, gerade wenn das Projekt erst mal richtig los geht, blickt man da 
sonst nicht mehr durch. Verstehe ich voll und ganz.


Wuensche euch allen ein schoenes Wochenende.

Gruss,

Malte


PS: Kann das Thema hier auch irgendwie geschlossen werden?
Ich kann naemlich verstehen, dass sich bei dem Betreff in Kombination 
mit meinem "Fehler" einige Leute zurecht getriggert fuehlen...

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
Noch kein Account? Hier anmelden.