Forum: Mikrocontroller und Digitale Elektronik Pointer Warning..


von Bahos (Gast)


Lesenswert?

Hallo Leute,
ich kompiliere mit GNUARM, und bekomme diese Warnung:

pointer of type 'void *' used in arithmetic

im Bezug auf diese Zeile:
1
void SetData(void* data)
2
{
3
 struct pbuf p;
4
 p->payload = 0x01 + 0x02 + data;
5
}
Weiss jemand was diese Warnung Bedeutet?

Danke!

von horst (Gast)


Lesenswert?

sollte das nicht + *data heißen? ^^

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Aber was wäre der Inhalt von data (*data), wenn data ein "Zeiger auf 
Nichts" (void *data) ist ;-)

von Bimmy and Jimmy (Gast)


Lesenswert?

sollte das nicht + *(my_type *) data heißen?
-> also ein Cast zu einem Pointer auf den Typ Deiner Wahl.
Woher soll der Compiler denn sonst wissen, auf was data zeigt,
schließlich ist das ja generisch (könnte z.B. auch ein struct sein)?
Und void - Zeiger darf man nicht einfach dereferenzieren!

Gruß
  Bimmy and Jimmy

von Bahos (Gast)


Lesenswert?

Danke für eure schnelle Antworten, vielleicht was ich noch sagen musste 
ist das payload auch einen void* pointer ist.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dann könnte eine Zuweisung

 p->payload = data;

Sinn machen.

Aber die Berechnung

 p->payload = 0x01 + 0x02 + data;

ist obskur. Was soll das bewirken?

von Uhu U. (uhu)


Lesenswert?

Der void * ist ein ganz spezieller Pointer: Er zeigt nicht auf einen 
Datentyp, sondern auf 'Nichts', Stefan "stefb" B. schon schrieb.

Bei gewöhnlichen Pointern wird Pointerarithmetik angewandt, wenn man 
damit rechnet. So macht der Compiler z.B. aus diesem Ausdruck

   int i[5] = { 0 };
   int *pI = i + 3;

folgende Berechnung:

   int *pI = (int *) ((char *) i + 3 * sizeof (int));

(Der Name eines Array-Objekts ohne Indizierung - i - ergibt einen 
Pointer auf das 0. Element!)

Da ein void * auf ein unbekanntes Objekt ohne Länge zeigt, ergibt 
Pointerarithmetik damit keinen Sinn, sondern ist ein Indiz für einen 
Fehler -- der wird vom Compiler angezeigt.

von Bahos (Gast)


Lesenswert?

Ich möchte die zwei Byte im Kopf der Puffer schreiben, das ist aber 
schwachsinnig wie ich das gemacht habe, ich kann doch einen Pointer 
keine Daten zuweisen aber eine Adresse.Habt ihr eine Idee wie ich das am 
besten machen kann?

von Bimmy and Jimmy (Gast)


Lesenswert?

In diesem Fall kannst Du deinen generischen Pointer in einen
unsigned long Wert umwandeln. Dieser Typ ist per Definition
hinreichend groß, um einen beliebigen Pointer aufzunehmen.
Danach kannst Du diesen Wert ändern und zuweisen.
Kleines Beispiel:
1
#include <stdio.h>
2
3
int bla (void *f)
4
{
5
void *p;
6
unsigned long q;
7
8
        q = (unsigned long) f;
9
        q += 3;
10
        p = (void *)q;
11
12
        printf ("%p => %p\n", f, p);
13
}
14
15
int main (void)
16
{
17
int a = 23;
18
        bla (&a);
19
        return 0;
20
}

Solche Probleme solltest Du im Allgemeinen aber eleganter lösen.
Gruß
Bimmy and Jimmy

von Bahos (Gast)


Lesenswert?

Ich danke euch Leute, manchmal braucht man eine Backpfeife um zu 
denken;-),
für die Leute, die sich dafür interessieren wie ich das gelöst habe:
1
void SetData(void* data, unsigned int DataSize)
2
{
3
 struct pbuf p;
4
 unsigned char* SrcBuffer; 
5
 unsigned char* DestBuffer;
6
7
 DestBuffer = (unsigned char*) p->payload;
8
 SrcBuffer  = (unsigned char*)data; 
9
 
10
 *(UDPBuffer++) = 0x01;
11
 *(UDPBuffer++) = 0x02;
12
13
 for (i = 0; i < DataSize;i++ ) 
14
  *(UDPBuffer++) = *(DataBuffer++);
15
}

von Bahos (Gast)


Lesenswert?

@Bimmy and Jimmy:
Danke dir, ich habe deine Antwort erst gesehen nachdem ich gepostet 
habe.

von Bahos (Gast)


Lesenswert?

Es gibt aber noch ein Problem, und zwar es wird immer eine Null dazu 
angehängt, woran kann das denn liegen?

von Uhu U. (uhu)


Lesenswert?

Ich würde mal sagen, das liegt daran, wie du den Wert für den Parameter 
DataSize bestimmst.

Aus deinem Codeausschnitt geht das leider nicht hervor.

von Bahos (Gast)


Lesenswert?

Den DataSize-Wert wird mittels SizeOf() bestimt, z.B:
1
unsigned char HAllO_MSG[] ='Hallo';
2
SetData(HAllO_MSG, sizeof(HAllO_MSG));

von Uhu U. (uhu)


Lesenswert?

Das dachte ich mir.

Wenn du sizeof "Hallo" berechnen läßt, kommt 6 heraus - warum wohl?

von Bahos (Gast)


Lesenswert?

Gibt es vielleicht eine andere Möglichkeit, wo diese Terminierungsnull 
nicht mitgezählt wird?

von Uhu U. (uhu)


Lesenswert?

strlen oder den Puffer nicht mit einem String initialisieren - macht 
hier eh wenig Sinn -, sondern die Länge in [] angeben. Das kann auch ein 
konstanter Ausdruck sein.

von Bahos (Gast)


Lesenswert?

> Das kann auch ein konstanter Ausdruck sein.
Ein Beispiel wäre super.
Danke.

von Uhu U. (uhu)


Lesenswert?

unsigned char HAllO_MSG[5];

oder

unsigned char HAllO_MSG[3 + 2];

Wie dirs besser gefällt ;-)

von Bahos (Gast)


Lesenswert?

Ich habe mir die erste Variante ausgesucht(strlen), vielen Dank!

von Uhu U. (uhu)


Lesenswert?

Das ist leider die aller schlechteste...

von Johnny Maxwell (Gast)


Lesenswert?

Wenn *data sowieso in einen (unsigned char*) gecastet wird, warum 
definierst du die Funktion dann nicht auch gleich so? Also:
1
void SetData(unsigned char *data, unsigned int DataSize);

Ich kann übrigens keinerlei Sinn in deinem obigen Code erkennen. Was 
soll der denn eigentlich machen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.