Forum: PC-Programmierung C: break in for-Schleife -> Schleifenzähler wird noch inkrementiert


von Ralf (Gast)


Lesenswert?

Hallo,

in einer for-Schleife prüfe ich den Wert einer Variablen gegen in einer 
Tabelle festgelegte Werte. Die Tabelle hat die Werte in aufsteigender 
Reihenfolge.
Ist die Variable kleiner als der durch den Schleifenzähler indizierte 
Wert aus der Tabelle soll die Schleife abgebrochen werden. Soweit tut 
das auch.

Das Problem ist nun, dass der Schleifenzähler offenbar noch um eins 
inkrementiert wird, ist das wirklich richtig? Ich brauch den 
Schleifenzähler um zu ermitteln, an welchem Index der Tabelle der Wert 
kleiner war.
Ich habe schon mehrere ähnliche Schleifenkonstrukte verwendet, und da 
hat's immer funktioniert, wenn ich mich recht entsinne.

Hier der Code:
1
for(ucIndex = 0; ucIndex < CONFIG_VAL_COUNT; ucIndex++) {
2
  if(uiValue <= uiValueTable[ucIndex])
3
    break;
4
}
Eigentlich nix komplexes... eigentlich...

Ralf

von Peter II (Gast)


Lesenswert?

Ralf schrieb:
> Eigentlich nix komplexes... eigentlich...

break ist break danach wird nichts inkrementiert. Warum debuggs du diese 
stelle nicht einfach?

von Ralf (Gast)


Lesenswert?

@Peter II:
> break ist break danach wird nichts inkrementiert. Warum debuggs du diese
> stelle nicht einfach?
Was glaubst du wie ich drauf gekommen bin, dass der Zähler inkrementiert 
wurde? :)

Ralf

von Peter II (Gast)


Lesenswert?

> Was glaubst du wie ich drauf gekommen bin, dass der Zähler inkrementiert
> wurde? :)
also nach dem du break ausfühst, wird  ucIndex noch mal geändert? steppe 
mal durch den ASM code. Beim break sollte nur ein jmp kommen mehr nicht.

von Karl H. (kbuchegg)


Lesenswert?

> Schleifenzähler um zu ermitteln, an welchem Index der Tabelle der Wert
> kleiner war.

Und warum schreibst du dann  <=

Da wird nix mehr inkrementiert. Du hast einen Logikfehler irgendwo.

von Ralf (Gast)


Lesenswert?

> also nach dem du break ausfühst, wird  ucIndex noch mal geändert?
Korrekt. Und das sollte m.E. nicht so sein. Deswegen meine Frage, ob das 
so richtig sei.

> steppe mal durch den ASM code. Beim break sollte nur ein jmp kommen mehr
> nicht.
Bin grad dabei. Vom ASM-Code her würd ich sagen es müsste sich korrekt 
verhalten, da über das Carry-Flag geprüft wird, ob auf den der Schleife 
folgenden Befehl gesprungen werden soll oder nicht. Falls nicht, wird 
der Zähler inkrementiert und an den Anfang der Schleife gesprungen.
Ich bin vorhin den C-Code durchgesteppt, und vom Ablauf her war's so, 
dass die if-Abfrage behandelt wurde, dann wurde auf den Schleifenkopf 
gesprungen, und DANN auf den nachfolgenden Befehl...
Das break wurde mir nicht als "aktiver" Befehl angezeigt.

PS: Ich seh grad, ich hab vergessen die Entwicklungsumgebung zu nennen:
Keil C51 Compiler (für 8051er Controller). Gepostet hab ich's in 
PC-Programmierung weil ich mir grad nicht sicher bin, ob dieses 
Verhalten in C erlaubt ist (und weil ich eben dachte dass der 
C51-Compiler dem C-Standard entspricht).

Mal schauen was das ASM-Steppen hervorbringt...

Ralf

von Ralf (Gast)


Lesenswert?

@Karl-Heinz:
> Und warum schreibst du dann  <=
Weil ich <= meinte und bei der Beschreibung das "oder gleich" vergessen 
habe, sorry.

> Da wird nix mehr inkrementiert. Du hast einen Logikfehler irgendwo.
Da WIRD aber inkrementiert. Was soll an dem bisschen C-Code einen 
Logikfehler haben? Lass mich bitte erstmal rausfinden, ob das a) 
C-Standard-Verhalten ist oder b) einfach ein Bug im Compiler ist.

Ralf

von Peter II (Gast)


Lesenswert?

zeig doch mal den asm code, eventuell sieht man ja etwas.

von Karl H. (kbuchegg)


Lesenswert?

Ralf schrieb:

> Logikfehler haben? Lass mich bitte erstmal rausfinden, ob das a)
> C-Standard-Verhalten ist oder b) einfach ein Bug im Compiler ist.

OK.
Im Klartext:
a) Es ist nicht C-Standard konform
b) Ich kann mir beim besten Willen nicht vorstellen, dass ein
   derartig elementarer Bug es durch die Compiler-Tests geschafft
   hätte

von Ralf (Gast)


Lesenswert?

Peter II, Karl-Heinz:
So wie's ausschaut haben wir alle recht:

Ralf schrieb:
> Was soll an dem bisschen C-Code einen Logikfehler haben?
Der Code hat keinen Fehler, ...

Peter II schrieb:
> break ist break danach wird nichts inkrementiert.
... ein break ist ein break, ...

Karl-Heinz schrieb:
> a) Es ist nicht C-Standard konform
..., doch, weil... (siehe ganz unten)

> b) Ich kann mir beim besten Willen nicht vorstellen, dass ein
>    derartig elementarer Bug es durch die Compiler-Tests geschafft
>    hätte
..., ich mir auch nicht, deswegen fragte ich ja, ...

> Du hast einen Logikfehler irgendwo.
..., doch wo mag er sein?

Was bleibt nach all dem noch übrig? Richtig, die Tabelle... Ich könnt 
kotzen, ich hab's bei den drei Debug-Versuchen geschafft, jedesmal den 
EINZIGEN Wert in der Tabelle zu erwischen, der falsch in der Reihenfolge 
ist ARGL

Ich danke euch beiden für die Hilfestellung, den ASM-Code genauer unter 
die Lupe zu nehmen hat mich schnell ans Ziel geführt. Und es 
bewahrheitet sich mal wieder etwas aus der C-Welt: Da wo sich der Fehler 
auswirkt muss er nicht unbedingt stecken... :)

Einen schönen Abend wünsche ich.

Ralf

von Vlad T. (vlad_tepesch)


Lesenswert?

das zeigt mal wieder:
der Fehler liegt zu 99.999% nicht im Compiler - und nein, man ist nicht 
der 0.001te Prozentpunkt.

Wobei auch compiler haben manchmal Bugs - ich hatte heute 2 nicht 
reproduzierbare Internal Compiler Errors im MSVC10

von Peter II (Gast)


Lesenswert?

Rolf Magnus schrieb im Beitrag #2529813:
> wenn sie nach der Schleife sowieso nicht mehr benutzt
> wird.
da ihm ja wichtig ist das der index stimmt, dann wird er ihn ja wohl 
auch verwenden.

von Andreas B. (andreas_b77)


Lesenswert?

Wenn du Optimierung an hast, zeigt dir der Debugger im Einzelschritt 
halt auch mal Seltsames an. Denn der Debugger zeigt den Quellcode an, 
verfolgt aber die Ausführung des optimierten Codes was nicht 1:1 dem 
Quellcode entspricht.

von Rolf M. (rmagnus)


Lesenswert?

Peter II schrieb:
> Rolf Magnus schrieb im Beitrag #2529813:
>> wenn sie nach der Schleife sowieso nicht mehr benutzt
>> wird.
> da ihm ja wichtig ist das der index stimmt, dann wird er ihn ja wohl
> auch verwenden.

Hätte ja sein können, daß er noch nicht soweit ist und schon bevor er 
das implementiert hat, im Debugger einen vermeintlich falschen Wert 
entdeckt hat.

von Ralf (Gast)


Lesenswert?

Guten Morgen zusammen,

Andreas B. schrieb:
> Wenn du Optimierung an hast, zeigt dir der Debugger im Einzelschritt
> halt auch mal Seltsames an. Denn der Debugger zeigt den Quellcode an,
> verfolgt aber die Ausführung des optimierten Codes was nicht 1:1 dem
> Quellcode entspricht.
Genau deswegen war ich ja so verwirrt als nach dem break nochmal in den 
Schleifenkopf gesprungen wurde. Ich hielt das vermeintlich für einen 
Bug.

Vlad Tepesch schrieb:
> das zeigt mal wieder:
> der Fehler liegt zu 99.999% nicht im Compiler - und nein, man ist nicht
> der 0.001te Prozentpunkt.
Naja, in dem Fall war ich ja das doch irgendwie :)

Rolf Magnus schrieb:
> Hätte ja sein können, daß er noch nicht soweit ist und schon bevor er
> das implementiert hat, im Debugger einen vermeintlich falschen Wert
> entdeckt hat.
Für gewöhnlich schreibe ich die Funktionen immer so komplett wie möglich 
und versuche dann in einem Rutsch rauszufinden, was alles nicht 
funktioniert :)

Ralf

von DirkB (Gast)


Lesenswert?

Ralf schrieb:
> Vlad Tepesch schrieb:
>> das zeigt mal wieder:
>> der Fehler liegt zu 99.999% nicht im Compiler - und nein, man ist nicht
>> der 0.001te Prozentpunkt.
> Naja, in dem Fall war ich ja das doch irgendwie :)

Nein, denn den Fehler hast du gemacht und nicht der Compiler.

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.