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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Malte H. (avr_alvarr)


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


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


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


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


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


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


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


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


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


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


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


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


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

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]
  • [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.