Forum: Mikrocontroller und Digitale Elektronik zeigerproblem


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von edka (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

Entscheide Dich:

Entweder um 1 erhöhen oder ReadFrame8900() zuweisen.

2 Zuweisungen gleichzeitig geht nicht.


Peter

von Khani (Gast)


Lesenswert?

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
}

von Khani (Gast)


Lesenswert?

sorry - nach Size -=2 fehlt ein ";"

von Khani (Gast)


Lesenswert?

Äh Peter, wie meinen ?
Bitte erleuchte mich, denn ich weiß nicht, was Du meinst ;-)

MfG, Khani

von edka (Gast)


Lesenswert?

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

von edka (Gast)


Lesenswert?

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();
}

von Khani (Gast)


Lesenswert?

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 ?

von Peter D. (peda)


Lesenswert?

@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

von Khani (Gast)


Lesenswert?

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++);

von Matthias (Gast)


Lesenswert?

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

von Martin (Gast)


Lesenswert?

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)?

von Martin (Gast)


Lesenswert?

"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?

von Oryx (Gast)


Lesenswert?

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

von Khani (Gast)


Lesenswert?

Zu meiner Ehrenrettung :

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

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

MfG, Khani

von Matthias (Gast)


Lesenswert?

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

von Matthias (Gast)


Lesenswert?

Hi

hab ich doch glatt das return 0; vergessen.

Matthias

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]
  • [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.