PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 1234 + 3 = 1235



Siro
05.12.2019, 09:05
Moin zusammen,
ich habe grade nach merkwürdigem Verhalten meiner Software gesucht,
Beim Abspecken auf das Nötigste enstand dann folgender Code, der nicht richtig funktioniert:
Wenn man den Wert 1234 drei mal inkrementiert sollte eigentlich 1237 rauskommen, der Wert "value" steht nach dem Aufruf der Funktion aber auf 1235.
Eigentlich eine schöne Prüfungsaufgabe ;)


void add(int* x)
{
*x=*x+1;
*x++;
*x+=1;
}

volatile int value;

void main(void)
{
value = 1234;
add(&value);
}


Siro

Klebwax
05.12.2019, 10:21
Operator Precedence heisst das Zauberwort.

Einfach den Code mal im Single Step laufen lassen, dann sieht mans. Schon bei " *x=*x+1; " kann man Bedenken haben: heißt das *x = *(x + 1) oder *x = (*x) + 1. Das geht aber noch gut. Aber bei *x++ gehts schief. Hier wird x um eins erhöht, dann derefferenziert und das Ergebniss ignoriert. Es müsste also heißen (*x)++. Für den Compiler mit seinen precedence Regeln steht dort aber *(x++). Jetzt zeigt x irgendwohin und die letzte Zeile inkrementiert diese Speicherstelle. Steht dort eine andere Variable, ist sie zerstört. Eine klassische Pointerfalle.

MfG Klebwax

P.S. Auf Anhieb hab ich das nur geahnt, der Debugger hat es mir aber gezeigt.

Siro
05.12.2019, 11:38
Ja ganz genau Klebwax,
ich habe es jedoch erst gemerkt beim durchforsten des Assemblercodes.
Durch die Klammerung (*x)++ funktioniert es dann richtig.

Man schreibt so oft p++ usw, dass es für mich mit *x++ "eigentlich/zunächst" logisch erschien...

Man bekommt aber vom Compiler (bei entsprechender Einstellung) eine Warnung bei *x++;
"value computed is not used"

Siro

Moppi
05.12.2019, 12:16
Was ist das für ein Compiler?


MfG
:Weihnacht

Klebwax
05.12.2019, 12:36
Ja ganz genau Klebwax,
ich habe es jedoch erst gemerkt beim durchforsten des Assemblercodes.

Dazu braucht man den Assemblercode nicht. Ich hab das im Debugger auf dem PC gesehen. Hatte ich glaub ich schon mal geschrieben, ich schau mir den Assemblercode weder auf nem µC, noch auf dem PC oder dem Raspi an.


Man schreibt so oft p++ usw, dass es für mich mit *x++ "eigentlich/zunächst" logisch erschien...

Ist verständlich, aber meisst anders gemeint. Bei "while (*p++)" z.B. auf ein char array will man ja, daß p nach dieser Operation p auf das nächste Zeichen zeigt. Ich schreib für deinen Fall lieber *p += 1, da muß man nicht lange nachdenken.


Was ist das für ein Compiler?

Spielt keine Rolle, ist einfach C.

MfG Klebwax