Forum: Compiler & IDEs While Schleife bricht nicht ab


von Andreas G. (andy1988)


Lesenswert?

Hallo,
ich habe grade versucht den folgenden Code auf einem Mega168 zu benutzen
1
#include "utils/strings.h"
2
3
unsigned char itoa(unsigned int uiVal, char* pBuff)
4
{
5
  unsigned char ucIndex = 0;
6
  unsigned char ucHelper = 0;
7
  unsigned char ucLenght = 0;
8
  
9
  char cDigit;
10
  
11
  do
12
  {
13
    cDigit = '0' + uiVal % 10;
14
    pBuff[ucIndex++] = cDigit;
15
  }
16
  while(uiVal /= 10);
17
  
18
  ucLenght = ucIndex;
19
  pBuff[ucIndex--] = 0;
20
  
21
  while(ucHelper < ucIndex)
22
  {
23
    cDigit = pBuff[ucIndex];
24
    pBuff[ucIndex--] = pBuff[ucHelper];
25
    pBuff[ucHelper++] = cDigit;
26
  }
27
  
28
  return ucLenght;
29
}

Das Teil soll einfach einen Integer in einen ASCII String umwandeln. Das 
hat auch mal funktioniert, als ich es in nem C++ Projekt benutzt habe. 
Jetzt ist es in C-Projekt.

Allerdings bricht die obere while Schleife nicht ab. Ich hab mir per 
UART mal uiVal ausgeben lassen und das ist irgendwann 0. Allerdings 
scheint die Abbruchbedingung die Schleife absolut nicht zu kratzen. Der 
rennt da fröhlich weiter drin rum und schreibt den RAM voll.


Ich bin langsam so durcheinander, dass ich vorne und hinten 
verwechsel... Mal besser ne Pause machen.

Achso... Fragt mich nicht, warum ich nicht die stdlib.h nutze. Tu ich 
gleich. Nur will ich jetzt einfach wissen, wieso der Scheiß da nicht 
funktioniert grr

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

"uiVal /= 10" ist eine Zuweisung.
Mach mal eine Bedingung daraus.

von Andreas G. (andy1988)


Lesenswert?

In C++ scheint das allerdings wunderbar zu funktionieren!
1
A property that C++ has over other programming languages is that the assignment operation can be used as the rvalue (or part of an rvalue) for another assignment operation. For example:
2
3
a = 2 + (b = 5);
4
5
is equivalent to:
6
7
b = 5;
8
a = 2 + b;
http://www.cplusplus.com/doc/tutorial/operators.html

Entweder da kommt bei mir oben was gleich 0 oder ungleich 0 raus.
Gleich 0: false
Ungleich 0: true


Aber damit wäre geklärt, warum das nicht geht. In C scheint das nicht so 
zu sein ;)


edit:
Grade getestet.
Beispiel in C++:
1
#include <iostream>
2
using namespace std;
3
4
int main(void)
5
{
6
        do
7
        {
8
                cout << "hallo" << endl;
9
        }
10
        while(0);
11
12
        do
13
        {
14
                cout << "hallo2" << endl;
15
        }
16
        while(1);
17
18
        return 0;
19
}

Die 2. Schleife läuft ewig.

von Andreas G. (andy1988)


Lesenswert?

Hmm... Nochmal editieren darf ich nicht ;)

So... Um nochmal Klarheit zu schaffen: Es ist eine C++ Eigenheit, dass 
der Rückgabewert einer Zuweisung der rechtsseitige Wert der selbigen 
ist. Somit funktioniert der Kram von mir da oben in C++ aber nicht in C.
Das is aber auch dreckig ;)

von Detlev T. (detlevt)


Lesenswert?

Andreas Galauner wrote:
> So... Um nochmal Klarheit zu schaffen: Es ist eine C++ Eigenheit, dass
> der Rückgabewert einer Zuweisung der rechtsseitige Wert der selbigen
> ist. Somit funktioniert der Kram von mir da oben in C++ aber nicht in C.
> Das is aber auch dreckig ;)

??? Das ist doch in ANSI-C genau so. Eigentlich müsste die Routine 
meiner Meinung nach funktionieren, wenn die Operationen korrekt 
ausgeführt werden.

PS: Da der Mega-AVR Divisionen in Software ausführen muss, ist das kein 
effizientes Verfahren zur Umwandlung.

Und warum heißt die Funktion eigentlich itoa, wenn du unsigned(!) int 
umwandeln willst. Verwirrst du dich gern selbst?

von Andreas G. (andy1988)


Lesenswert?

Naja... Sie geht nicht ;)
Und ob effizient oder nicht is jetzt auch egal. Ich will nur wissen, 
wieso das nicht funktioniert. Die einzige Erklärung die ich dazu hab ist 
wirklich, dass aus der Zuweisung immer irgendwas != 0 rauskommt. Weiß 
der Geier wieso.

>Und warum heißt die Funktion eigentlich itoa, wenn du unsigned(!) int
>umwandeln willst. Verwirrst du dich gern selbst?
Verwirrt mich nicht. Ich hab ja ne Parameterliste ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du weißt aber, dass es ein itoa() in der Bibliothek gibt?

von Andreas G. (andy1988)


Lesenswert?

Jörg Wunsch wrote:
> Du weißt aber, dass es ein itoa() in der Bibliothek gibt?

Ich zitier mich mal selbst:
>Achso... Fragt mich nicht, warum ich nicht die stdlib.h nutze. Tu ich
>gleich. Nur will ich jetzt einfach wissen, wieso der Scheiß da nicht
>funktioniert *grr*

von (prx) A. K. (prx)


Lesenswert?

Ich sehe keinen Grund, warum die Schleife nicht funktionieren sollte. Ob 
C oder C++, es gilt immer noch, dass alle assign-ops den abschliessenden 
Wert der linken(!) Seite wiederspiegeln, und das in diesem Zusammenhang 
bekanntere "++i" ist exakt äquivalent zu "i += 1".

von Oliver (Gast)


Lesenswert?

WinAVR20071221 produziert erwartungsgemäß für
1
while(uiVal /= 10);
und
1
while((uiVal /= 10)!=0);

(mit Optimierung -Os) exakt den gleichen Code.

Oliver

von Detlev T. (detlevt)


Lesenswert?

Im Simulator von AVR Studio bricht bei mir die Schleife ab. (testwerte 
0, 10, 1234).

Welche Revision des Compilers benutzt du denn? Vielleicht gibt es da ja 
einen bereits dokumentierten Bug.

von Andreas G. (andy1988)


Lesenswert?

AVR-GCC 4.3.0
Aus dem AVR MacPack: http://www.obdev.at/products/avrmacpack/index.html

Allerdings mit dem GNU99 Standard kompiliert. Sollte aber nicht so viel 
dran ändern, oder?

von Manuel Stahl (Gast)


Lesenswert?

Teste doch mal obs an dem Zuweisungsproblem liegt:
1
#include "utils/strings.h"
2
3
unsigned char itoa(unsigned int uiVal, char* pBuff)
4
{
5
  unsigned char ucIndex = 0;
6
  unsigned char ucHelper = 0;
7
  unsigned char ucLenght = 0;
8
  
9
  char cDigit;
10
  
11
  do
12
  {
13
    cDigit = '0' + uiVal % 10;
14
    pBuff[ucIndex++] = cDigit;
15
    uiVal /= 10;
16
  }
17
  while(uiVal);
18
  
19
  ucLenght = ucIndex;
20
  pBuff[ucIndex--] = 0;
21
  
22
  while(ucHelper < ucIndex)
23
  {
24
    cDigit = pBuff[ucIndex];
25
    pBuff[ucIndex--] = pBuff[ucHelper];
26
    pBuff[ucHelper++] = cDigit;
27
  }
28
  
29
  return ucLenght;
30
}

Das sollte ja dann gehen. Ich hab aber schon öfter bemerkt, dass der GCC 
eine Warnung ausgiebt, wenn man sowas schreibt:
1
if(a = b) {
2
 ...
3
}

von holger (Gast)


Lesenswert?

>Das sollte ja dann gehen. Ich hab aber schon öfter bemerkt, dass der GCC
>eine Warnung ausgiebt, wenn man sowas schreibt:

>if(a = b) {

Jupp, dann sollte man weitere Klammern setzen:

if((a = b)) {

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Manuel Stahl wrote:

> Ich hab aber schon öfter bemerkt, dass der GCC
> eine Warnung ausgiebt, wenn man sowas schreibt:
>
>
1
> if(a = b) {
2
>  ...
3
> }
4
>

Klar, weil es ein häufiger Flüchtigkeitsfehler ist, dass man bei einem
Vergleich auf Gleichheit eins der beiden Gleichheitszeichen vergisst.

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.