mikrocontroller.net

Forum: Compiler & IDEs Verständnisfrage postdecrement


Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)
#include <avr/io.h>            
#include <avr/eeprom.h>
#include <stdint.h>

#define EEPROM_ID       1           //byte 1    The ID of the node. The location table of the nodes is in file nodeloactiontable.txt        
#define EEPROM_WDRF     2           //byte 2    WDRF-counter; counts how often watchdog WDRF caused a reset
#define EEPROM_BORF     3           //byte 3    BORF-counter; counts how often brownout BORF caused a reset           
#define EEPROM_EXTRF    4           //byte 4    EXTRF-counter; counts how often external reset EXTRF caused a reset           
#define EEPROM_PORF     5           //byte 5    PORF-counter; counts how often power on reset PORF caused a reset

void Mcusr_check (void)
{
    uint8_t mcusr = MCUSR;
    MCUSR = 0;
    uint8_t *eepromaddress_ptr = 0;
    uint8_t reset_counter =0;
    if (mcusr & (1<<WDRF))
    {
        *eepromaddress_ptr = EEPROM_WDRF;
    }
    else if (mcusr & (1<<BORF))
    {
        *eepromaddress_ptr = EEPROM_BORF;
    }
    else if (mcusr & (1<<EXTRF))
    {
        *eepromaddress_ptr = EEPROM_EXTRF;
    }
    else if (mcusr & (1<<PORF))
    {
        *eepromaddress_ptr = EEPROM_PORF;
    }
=>  reset_counter++ = eeprom_read_byte (eepromaddress_ptr);
    eeprom_write_byte (eepromaddress_ptr, reset_counter);
};

=> 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.

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht 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
reset_counter = eeprom_read_byte (eepromaddress_ptr)+1;
?

MfG Mark

Autor: Luther Blissett (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.