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


von Jan (Gast)


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

von noch ein gast (Gast)


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.

von Jan (Gast)


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

von Karl H. (kbuchegg)


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.

von Sven P. (Gast)


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).

von Unbekannter (Gast)


Lesenswert?

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

von Michael G. (linuxgeek) Benutzerseite


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.

von Jan (Gast)


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.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Klar, da darf ein beliebiger Ausdruck stehen ;)

von Karl H. (kbuchegg)


Lesenswert?

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

von Εrnst B. (ernst)


Lesenswert?

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

Weil das ein '\0' am Stringende mitkopiert?

von Karl H. (kbuchegg)


Lesenswert?

Ernst Bachmann wrote:
> Karl heinz Buchegger wrote:
>> Wobei ich mich frage, warum du nicht ganz einfach
>> das für strings vorgesehene strcpy benutzt
>>
>>
1
>>    strcpy( header, name );
2
>>
>
> 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.

von Unbekannter (Gast)


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.

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.