www.mikrocontroller.net

Forum: Compiler & IDEs struct probleme


Autor: Elektro Gandalf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe mal wieder ein Problem!
Folgendes habe ich Programmiert (nur mal so zum Test):
struct daten
{
  uint8_t datum1;
  uint8_t datum2;  
  uint8_t datum3;
};


typedef struct daten  RSD;
typedef RSD* PRSD;


void bearbeitedaten(PRSD myrs232daten);


int main(void) 
{ 
  PRSD myrs232daten;

  bearbeitedaten(&myrs232daten);

}

void bearbeitedaten(PRSD myrs232daten)
{
  myrs232daten->datum1 = 1;
  myrs232daten->datum2 = 2;
  myrs232daten->datum3 = 3;
}



das Programm funktioniert der Compiler (GCC-Version: 4.1.1 (WinAVR 
20070122))
bringt mir jedoch folgende Warnung:

main.c:68: warning: passing argument 1 of 'bearbeitedaten' from 
incompatible pointer type

Was mache ich falsch?

Autor: Hartmut Semken (hsemken)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  PRSD myrs232daten;
  char c;

damit ist das Symbol myrs232daten ein Pointer (auf ein struct) und c ist 
ein char.

&c ist dann ein Pointer, nämlich einer, der auf ein char namens c zeigt.
Was ist dann wohl &myrs232daten?

Richtig: der alte MacOS-Programmierer würde sagen: ein Handle. Ein 
Pointer auf einen Pointer auf ein struct.

Ein Pointer auf ein struct und ein Pointer auf einen Pointer sind beides 
Pointer, aber eben nicht kompatible Typen.

Allerdings kann ich mir kaum vorstellen, dass das Programm funktioniert.
Ich würde empfehlen, das mal im Debugger genauer anzusehen und für die 
diversen verschiedenen Objekte die Adressen zu ermitteln.

Man korrigiere mich, wenn mich mein angerostetes C hier täuscht :-)

Gruß
hase

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Elektro Gandalf wrote:
> Hallo,
>
>
> struct daten
> {
>   uint8_t datum1;
>   uint8_t datum2;
>   uint8_t datum3;
> };
> 
> 
> typedef struct daten  RSD;
> typedef RSD* PRSD;
> 
> 
> void bearbeitedaten(PRSD myrs232daten);
> 
> 
> int main(void)
> {
>   PRSD myrs232daten;
> 
>   bearbeitedaten(&myrs232daten);
> 
> }
> 
> void bearbeitedaten(PRSD myrs232daten)
> {
>   myrs232daten->datum1 = 1;
>   myrs232daten->datum2 = 2;
>   myrs232daten->datum3 = 3;
> }
> 
> 
> 
>
> das Programm funktioniert

Das wage ich zu bezweifeln.
Es mag so aussehen, aber es hat definitiv einen schwerwiegenden
Bug (oder aber du hast das Programm hier neu eingetippt und
das Programm das du compilierst ist ein anderes als das welches
du hier gepostet hast).

int main(void)
{
  PRSD myrs232daten;

  bearbeitedaten(&myrs232daten);

myrs232daten ist vom Typ PRSD, welcher seinerseit ein RSD*,
also bereits ein Pointer auf struct daten ist.

&myrs232daten hat daher den Datentyp struct daten**
und da die Funktion bearbeitedaten einen struct daten* haben
will, müsste der Compiler eigentlich anmerken, dass du hier
einen Datentyp-mismatch hast.


Ich weiss, dass jeder C Programmierer irgendwann die Phase
durchmacht, in der er denkt, dass ein typedef ala

typedef RSD* PRSD;

eine gute Idee ist. Sie ist es selten und die meisten Programmierer
hören nach kurzer Zeit wieder damit auf. Einen * im tatsächlichen
Source Code zu haben, ist weit weniger schlimm, als sich ständig
merken zu müssen, welcher typedef nun für einen Pointer und welcher
nur für eine Struktur steht (selbst wenn man den typedef Namen
mit einem P einleitet, oder wie andere es machen den Namen mit
_P beendet [ typedef struct daten RSD_P ])

int main(void)
{
  RSD myrs232daten;

  bearbeitedaten(&myrs232daten);
}

void bearbeitedaten(RSD * myrs232daten)
{
  myrs232daten->datum1 = 1;
  myrs232daten->datum2 = 2;
  myrs232daten->datum3 = 3;
}

Wenn du dich daran erinnern willst, das das was du hast
ein Pointer ist, dann ist eine beliebte Methode, den Variablen-
namen mit einem p beginnen zu lassen und den Rest mittels
Camel-Case in Gross-Kleinschreibung lesbarer zu machen:

void bearbeiteDaten(RSD * pDaten)
{
  pDaten->datum1 = 1;
  pDaten->datum2 = 2;
  pDaten->datum3 = 3;
}

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ist es.

bearbeitedaten(PRSD myrs232daten) möchte einen pointer auf dein struct 
als Parameter haben, mit

PRSD myrs232daten;
bearbeitedaten(&myrs232daten);

übergibst du einen Pointer auf einen Pointer. Das geht gründlich schief.

Das Problem kommt daher, daß du deinen Variablen und Typen nicht ansehen 
kannst, ob sie nun Daten oder Pointer sind. Entweder lässt du den 
Quatsch mit dem "typedef PSRD", oder du nennst myrs232daten z.B. 
p_myrs232daten. Denn das ist ein pointer, und kein Datenfeld.

Und dann erkennst du auch, warum dein Programm auch mit dem 
warnungsfreien Aufruf

bearbeitedaten(myrs232daten);

gnadenlos abstürzen wird.

Oliver

Autor: Elektro Gandalf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK danke mal!

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.