mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik warning: operation on "i" may be undefined


Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
was soll diese Warnung?

Ich habe den folgenden Codeausschnitt, den er bemängelt:

uint8_t i= 0;

while(name[i] != 0)
  header[i] = name[i++];

Wieso sollte i undefiniert sein?

Gru0
Jan

Autor: noch ein gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht i ist undefiniert, sondern die damit durchgeführte Operation.

i++ wird nach dem Auslesen des Arrays name durchgeführt, aber es ist 
nicht sichergestellt, daß dies erst nach dem Zuweisen an das Array 
header geschieht.

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay danke.

Und warum ist das so? Ich schreibe doch gerade grade den POSTfix 
Operator hin, damit es danach erst inkrementiert wird...

Gruß
Jan

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist das i auf der linken Seite der Zuweisung.
Welches i ist das? Der Wert vor dem Erhöhen oder nach
derm Erhöhen.
Der C Standard stellt es dem Compiler frei was in so einem
Fall geschehen soll. Es ist undefiniert welcher Wert hier zum
Zug kommt.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> header[i] = name[i++];

i wird hier zweimal benutzt, links und rechts. Aber es ist nicht 
festgelegt, wann i inkrementiert wird.

Beachte die Reihenfolge:
Fall 1:
  1. Adresse von header[i] merken (= linke Seite auswerten)
  2. Wert von name[i] ermitteln und i erhöhen (= rechte Seite auswerten)
  3. Zuweisung durchführen

Fall 2:
  1. Wert von name[i] ermitteln und i erhöhen (= rechte Seite auswerten)
  2. Adresse von header[i] merken (= linke Seite auswerten)
  3. Zuweisung durchführen

Im zweiten Fall würde "header[i]" schon mit dem erhöhten "i" arbeiten. 
Welcher Fall eintritt, ist eben undefiniert (= zufällig).

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

for ( uint8_t i=0; name[i]; i++ )
  header[i] = name[i];


Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan wrote:
> Hallo,
> was soll diese Warnung?
>
> Ich habe den folgenden Codeausschnitt, den er bemängelt:
>
> uint8_t i= 0;
>
> while(name[i] != 0)
>   header[i] = name[i++];

Yups... noch nen bisschen ungluecklicher kann man das eigentlich nicht 
schreiben. In solchen Faellen for benutzen.

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:)

Dass ich in der for-Schleife die Abbruchbedingung auch für die Prüfung 
name[i] != 0 nutzen kann, hab ich nicht bedacht.

Danke.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar, da darf ein beliebiger Ausdruck stehen ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wobei ich mich frage, warum du nicht ganz einfach
das für strings vorgesehene strcpy benutzt
   strcpy( header, name );

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Wobei ich mich frage, warum du nicht ganz einfach
> das für strings vorgesehene strcpy benutzt
>
>
>    strcpy( header, name );
> 

Weil das ein '\0' am Stringende mitkopiert?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ernst Bachmann wrote:
> Karl heinz Buchegger wrote:
>> Wobei ich mich frage, warum du nicht ganz einfach
>> das für strings vorgesehene strcpy benutzt
>>
>>
>>    strcpy( header, name );
>> 
>
> Weil das ein '\0' am Stringende mitkopiert?

Ich wette um ein Bier mit dir, dass der OP genau das eigentlich
will und nur noch nicht weiß, dass er hier in seiner Version
einen Programmfehler hat.

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich wette um ein Bier mit dir, dass der OP genau das eigentlich
> will und nur noch nicht weiß, dass er hier in seiner Version
> einen Programmfehler hat.

Das ist ein Argument. Dagegen würde ich nicht wirklich wetten wollen.

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.