Verständnisfrage postdecrement

Gast #821185
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.
#821209
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren