Forum: Compiler & IDEs Verständnisfrage postdecrement


von Lutz (Gast)


Lesenswert?

Hallo,

laut meinen bisherigen C-Kenntnissen bedeutet variable++, daß variable 
erst in dem Ausdruck verwendet wird und dann um 1 erhöht wird. Warum 
meckert der Compiler (WinAVR 20071221 bzw. avr-gcc 4.2.2) in folgendem 
Ausdruck (wo "=>" steht)
1
#include <avr/io.h>            
2
#include <avr/eeprom.h>
3
#include <stdint.h>
4
5
#define EEPROM_ID       1           //byte 1    The ID of the node. The location table of the nodes is in file nodeloactiontable.txt        
6
#define EEPROM_WDRF     2           //byte 2    WDRF-counter; counts how often watchdog WDRF caused a reset
7
#define EEPROM_BORF     3           //byte 3    BORF-counter; counts how often brownout BORF caused a reset           
8
#define EEPROM_EXTRF    4           //byte 4    EXTRF-counter; counts how often external reset EXTRF caused a reset           
9
#define EEPROM_PORF     5           //byte 5    PORF-counter; counts how often power on reset PORF caused a reset
10
11
void Mcusr_check (void)
12
{
13
    uint8_t mcusr = MCUSR;
14
    MCUSR = 0;
15
    uint8_t *eepromaddress_ptr = 0;
16
    uint8_t reset_counter =0;
17
    if (mcusr & (1<<WDRF))
18
    {
19
        *eepromaddress_ptr = EEPROM_WDRF;
20
    }
21
    else if (mcusr & (1<<BORF))
22
    {
23
        *eepromaddress_ptr = EEPROM_BORF;
24
    }
25
    else if (mcusr & (1<<EXTRF))
26
    {
27
        *eepromaddress_ptr = EEPROM_EXTRF;
28
    }
29
    else if (mcusr & (1<<PORF))
30
    {
31
        *eepromaddress_ptr = EEPROM_PORF;
32
    }
33
=>  reset_counter++ = eeprom_read_byte (eepromaddress_ptr);
34
    eeprom_write_byte (eepromaddress_ptr, reset_counter);
35
};

=> error: lvalue required as left operand of assignment

Nun ja, was hindert ihn jetzt daran, erst den linken Wert zu nehmen, um 
die Zuweisung zu machen und danach diesen Wert dann um 1 zu erhöhen?
Wenn ich die Zeile "auseinanderziehe"

reset_counter = eeprom_read_byte (eepromaddress_ptr);
reset_counter++;

gibt es kein Problem. Gefällt mir sogar besser, da "Schritt für Schritt" 
zumindest als Anfänger noch einfacher nachvollziehbar. Ist aber halt 
eine Grundsatzfrage.

P.S.: Mit diesem vielleicht etwas merkwürdig ausschauenden 
EEPROM-Konstrukt verfolge ich folgende Idee: Auf einem CAN-Bus haben 
alle uC die gleiche Software (wegen späterem update per Bootloader). Die 
individuellen Parameter jedes uC will ich im EEPROM ablegen und beim 
Starten mit fester Adresstabelle einlesen.

von Mark .. (mork)


Lesenswert?

Hallo Lutz,

genauso wie Du z.b. einer Summe keinen Wert zuweisen kannst (a+b=c) 
kannst Du es auch nicht bei einer inkrementierten Variable tun. Was 
spricht gegen ein einfaches
1
reset_counter = eeprom_read_byte (eepromaddress_ptr)+1;
?

MfG Mark

von Luther B. (luther-blissett)


Lesenswert?

Lutz wrote:
> reset_counter = eeprom_read_byte (eepromaddress_ptr);
> reset_counter++;
>
> gibt es kein Problem. Gefällt mir sogar besser, da "Schritt für Schritt"
> zumindest als Anfänger noch einfacher nachvollziehbar. Ist aber halt
> eine Grundsatzfrage.

Mir gefällt
reset_counter = 1+eeprom_read_byte (eepromaddress_ptr);
noch besser

Das Ergebnis von post-increment ist kein l-value, weil es einen 
Seiteneffekt hat: Auf der rechten Seite des "=" kann ein beliebiger 
Ausdruck stehen, in diesem Fall ein Funktionsaufruf. Ein Funktionsaufruf 
stellt aber einen sog. sequence point dar, d.h. laut C-Standard müssen 
die Seiteneffekte die vor dem Funktionsaufruf angestossen wurden, 
abgeschlossen sein, d.h. bevor eeprom_read_byte aufgerufen wird, müsste 
reset_counter bereits inkrementiert sein! Wenn die Zuweisung also gehen 
würde, dann müsste sie so was wie das hier bedeuten:

reset_counter++
reset_counter = eeprom_read_byte (eepromaddress_ptr);

Verrückt nicht? Das ist es besser keinen l-value zu haben.

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.