zeigerproblem

Gast #66752
Hallo,
habe folgendes Problem. Mein C Compiler meckert in der markierten
Zeile.
Leider habe ich wenig ahnung wie dieser Zeiger funktioniert.
Der Compiler hat ein Problem mit der Inkrementierung.
Kann einer von euch Experten den Code umschreiben, dass die Umwandlung,
Inkrementierung und die Zuweisung nicht mit einem Aufruf vollzogen
wird.
Evtl. eine hilfvariable?

gruß

edka



void CopyFromFrame8900(void *Dest, unsigned int Size)
{
while (Size > 1)
{
(*(unsigned char *)Dest)++ = ReadFrame8900();
Size -= 2;
}
}



Compiler IAR Embedded Workbench 3.22

Fehlermeldung: not a modifyable lvalue
Gast #66754
Also nach C/C++ müsste das auch so gehen :

void CopyFromFrame8900(void *(&Dest), unsigned int Size)
{
    while (Size > 1)
    {
        (*(unsigned char *)Dest)++ = ReadFrame8900();
        Size -= 2;
    }
}

Wenn man einfach die Typkonversion und die Inkremetierung
auseinanderreisst, dann ist "Dest" selbst (also die Adresse, wo der
Pointer hinzeigt) immer noch nicht modifizierbar (zumindest wirkt sich
das nicht auf das Hauptprogramm aus). Das & zeigt an, dass diese
Variable ebenfalls verändert wird.

Meiner Meinung nach ist das eh kein guter Stil, aber ich gehe davon
aus, dass die Funktion nicht anders geschrieben werden konnte. Falls
man sie anders schreiben könnte :

void CopyFromFrame8900(void *Dest, unsigned int Size)
{
    cDest = (unsigned char*)Dest);
    while (Size >1)
    {
        cDest = ReadFrame8900(); // was macht eignetlich Read... ?
        cDest++;
        Size -= 2
    }
}

Mögliche andere Fehlerquelle : poste mal die Deklaration von
ReadFrame8900(), wenn die nämlcih keinen so tollen Rückgabetyp hat,
dann kann man das so eh nicht machen.

MfG, Khani
}
Gast #66757
Danke für die schnellen antworten.
Hier die Deklaration von ReadFrame8900()

unsigned int ReadFrame8900(void)
{
  unsigned int ReturnValue;

  P5DIR = 0x00;                                  // data port to input
  P3OUT = IOR | IOW | RX_FRAME_PORT;             // access to
RX_FRAME_PORT

  P3OUT &= ~IOR;                                 // IOR-signal low

  ReturnValue = P5IN;                            // get 1st byte from
data bus (low-byte)
  P3OUT = IOR | IOW | (RX_FRAME_PORT + 1);       // IOR high and put
next address on bus
  P3OUT &= ~IOR;                                 // IOR-signal low

  ReturnValue |= P5IN << 8;                      // get 2nd byte from
data bus (high-byte)

  P3OUT |= IOR;

  return ReturnValue;
}

gruß

edka
Gast #66758
Wenn ich es so schreibe meckert der Compiler nicht, funkt aber trotzdem
nicht.

void CopyFromFrame8900(void *Dest, unsigned int Size)
{
  while (Size > 1)
   {

   (*(unsigned int *)Dest)++;
    *(unsigned char *)Dest = ReadFrame8900();


    Size -= 2;
  }

  if (Size)
 *(unsigned char *)Dest = ReadFrame8900();
}
Gast #66759
Oh Oh...
Das macht die Sache aber noch ein bißchen komplexer...
Dann lieber so :

void CopyFromFrame8900(void *Dest, unsigned int Size)
{
    unsigned char* cDest = (unsigned char*)Dest;
    while (Size >1)
    {
        *cDest = (unsigned char)ReadFrame8900();
        cDest++;
        Size -= 2;
    }
}

Oder nicht Peter ?
#66760
@Khani

"Bitte erleuchte mich, denn ich weiß nicht, was Du meinst ;-)"


Die Zeile macht doch 2 Zuweisungen auf die selbe Variable, auseinander
geschrieben also folgendes:

(*(unsigned char *)Dest)++;

*(unsigned char *)Dest = ReadFrame8900();


Ist aber in der Regel sinnlos, da die erste Zuweisung ja sofort von der
2. überschrieben wird.


Peter
Gast #66761
Nochmal Peter :

Vereinfach wir die Sache mal etwas :

a++ = b;

Das ergibt meiner Meinung nach folgendes :

a = b;
a++;

das heißt Ergebnis in a : b+1

Was Du meinst ist glaube ich : ++a = b;

in diesem Falle passiert, was Du schreibst :

++a;
a = b;

Ergebnis in a : b (also war das mit dem "++" überflüssig)

MfG Khani.

P.S.: es gibt da doch dieses Idiom zum Stringkopieren, daher meine
Meinung :

while (dest++ = source++);
Gast #66762
Hi

a++ = b; dürfte kein gültiges C sein da zwei Zuweisungen auf ein und
die selbe Variable angewendet werden. Einmal a=a+1 und einmal a=b. Der
GCC meckert das auch mit der Fehlermeldung

config.c:125: error: invalid lvalue in assignment

an.

Matthias
Gast #66763
a++ = b;  // darf man wie gesagt auf keinen fall


@edka:
was übergibst du mit Dest (Eine Adresse, ein Array voller Adressen,
...), und soll die Adresse auf die Dest zeigt erhöht werden, oder die
Variable die von ReadFrame zurückgegeben wird (schätze mal erstes)?
Gast #66764
"oder die
Variable die von ReadFrame zurückgegeben wird (schätze mal erstes)?"


sollte heißen:
oder der Wert der von ReadFrame zurückgegeben wird um eins erhöht
werden?
Gast #66765
Hallo,
a++ = b;  // darf man wie gesagt auf keinen fall

aber
*(a++) = b; // sollte Compilierbar sein

Wert von b dahin kopieren, wohin der Pointer zeigt. Danach den Pointer
um eins erhöhen.

Eine offensichtlichere Schreibweise wäre
*a = b;
a++;

Die Lösung des eigentlichen Problems könnte sein:
*((unsigned char *)Dest)++) = ReadFrame8900();

besser:
*((unsigned char *)Dest)= ReadFrame8900();
((unsigned char *)Dest)++;

wenn ich mich mit den Cast und der Klammerei nicht versehen habe

Oryx
Gast #66766
Zu meiner Ehrenrettung :

ich hatte bei meiner Vereinfachung folgendes vorausgesetzt :
unsigned int a, b;

Dann geht's. (Der Compiler gibt mir recht)

MfG, Khani
Gast #66767
Hi

@Khani

Dann ist aber dein Compiler ziemlich kaputt oder zeigt undefiniertes
Verhalten.
Mein GCC (in der Inkarnation AVRGCC und der von Cygwin) meckert mir das
mit der gennanten Fehlermeldung an.

Programm:

#include <stdio.h>

int main(void)
{
  unsigned int a,b;

  a=4;
  b=4;

  a++=b;

  printf("%d\n%d\n",a,b);
}

Was sollte den dieses Programm deiner Meinung nach ausgeben?

Matthias

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 22 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.