Hallo zusammen, ich möchte einer Funktion in C einen Pointer übergeben, völlig unabhängig vom Typen, auf den der Pointer zeigt. Wie kann ich den Compiler dazu bringen bei diesem Pointer den dereferenzierten Datentypen nicht zu prüfen? Der Pointer soll nach dem Dereferenzieren immer auf ein Byte zeigen, d.h. ich möchte der Funktion die Startadresse einer Variable eines beliebigen Datentyps übergeben. Auf diese Variable möchte ich byteweise lesend oder schreibend zugreifen. Hier: Beitrag "Ein Datentyp für alles" wurde mein Problem angegangen, ich verstehe die Funktionsweise allerdings nicht. Kann mich jemand aufklären? mfG. AnddnA
AnddnA schrieb: > Wie kann ich den > Compiler dazu bringen bei diesem Pointer den dereferenzierten Datentypen > nicht zu prüfen? void* myPointer
Du suchst einen void-Pointer. Den musst Du allerdings zum Dereferenzieren nach uint8_t* (oder "unsigned char*") casten.
1 | int bla(void* p) |
2 | {
|
3 | uint8_t* pp; |
4 | uint8_t meins; |
5 | |
6 | pp = (uint8_t *) p; |
7 | |
8 | meins = *pp; |
9 | }
|
Gebrauch:
1 | int x; |
2 | float y; |
3 | char* z; |
4 | |
5 | bla(&x); |
6 | bla(&y); |
7 | bla(&z); |
8 | |
9 | bla(z); |
:
Bearbeitet durch User
Vielen Dank für die Antworten. Es war doch einfacher als gedacht. Mir fehlte nur der Begriff "void Pointer". Mit dem void Pointer selber kann man anscheinend nicht viel machen. Man muss ihn, wie Rufus erwähnt hat, in einen Pointer auf einen bestimmten Datentyp casten. Das wollte ich noch einmal betonen, falls jemand die selben Fehler macht wie ich.
AnddnA schrieb: > Mit dem void Pointer selber kann man anscheinend nicht viel machen. Man > muss ihn, wie Rufus erwähnt hat, in einen Pointer auf einen bestimmten > Datentyp casten. Ich würde es anders ausdrücken: Der void-Zeiger gibt einem sehr große Flexibilität, man muss dann aber immer genau wissen, was hinter der Adresse auf die er zeigt zu erwarten ist. Schau dir mal die Implementierung des "Workerthreads" an, das ist ein sehr schönes Beispiel für die Anwendung des void-Zeigers.
AnddnA schrieb: > Man > muss ihn, wie Rufus erwähnt hat, in einen Pointer auf einen bestimmten > Datentyp casten. Das wollte ich noch einmal betonen, falls jemand die > selben Fehler macht wie ich. Das muß man nicht (und sollte es auch nicht). Casts sollte man - wann immer möglich - vermeiden, das ist eine (meist unnötige) Fehlerquelle, weil man dem Compiler die Möglichkeit zur Kontrolle nimmt. void pointer muß man nicht casten. Sie sind zuweisungskompatibel zu jedem beliebigen Pointer-Typ, also weist man sie sinnvollerweise zu:
1 | void test(void *pv) |
2 | {
|
3 | int *pi = pv; |
4 | char *pc = pv; |
5 | long *pl = pv; |
6 | }
|
so geht das ganz ohne Cast, ohne Fehler, ohne Warnung. Die "zusätzliche" Variable stört nicht. Der Compiler optimiert sie weg, wenn sie nicht gebraucht wird. Was man allerdings muß, ist - ohne Compilerhilfe - auf das richtige Alignment achten.
AnddnA schrieb: > Mit dem void Pointer selber kann man anscheinend nicht viel machen. Man > muss ihn, wie Rufus erwähnt hat, in einen Pointer auf einen bestimmten > Datentyp casten. Das wollte ich noch einmal betonen, falls jemand die > selben Fehler macht wie ich. Ist doch auch logisch, denn: AnddnA schrieb: > Auf diese Variable möchte ich byteweise lesend oder schreibend zugreifen. Das impliziert ja einen Datentyp, nämlich einen, der ein Byte groß ist. void* sagt aber, dass es keinerlei Informationen darüber gibt, was sich dahinter verbirgt - wie man darauf zugreifen kann und nicht einmal, wie groß es ist. Man kann also einen void* nicht dereferenzieren, da der Compiler nicht weiß, wie der das, wohin er zeigt, interpretieren soll.
:
Bearbeitet durch User
Markus F. schrieb: > so geht das ganz ohne Cast, ohne Fehler, ohne Warnung. ...jaja, ohne Warnung...bis man mal auf einem System, wo Alignment eine Rolle spielt, damit ganz übel auf die Nase fällt. Meine Meinung dazu sieht ganz anders aus: Man sollte void Pointer vermeiden und stattdessen sich Gedanken über eine bessere Struktur seiner Firmware machen, so daß man keine void Pointer benötigt. W.S.
W.S. schrieb: > Meine Meinung dazu sieht ganz anders aus: Man sollte void Pointer > vermeiden und stattdessen sich Gedanken über eine bessere Struktur > seiner Firmware machen, so daß man keine void Pointer benötigt. da schon malloc einen void zurück liefert, kann man wohl kaum auf void verzichten.
W.S. schrieb: > Markus F. schrieb: >> so geht das ganz ohne Cast, ohne Fehler, ohne Warnung. > > ...jaja, ohne Warnung...bis man mal auf einem System, wo Alignment eine > Rolle spielt, damit ganz übel auf die Nase fällt. > > Meine Meinung dazu sieht ganz anders aus: Man sollte void Pointer > vermeiden und stattdessen sich Gedanken über eine bessere Struktur > seiner Firmware machen, so daß man keine void Pointer benötigt. > > W.S. Naja, wenn man ein scharfes Messer hat, sollte man wissen, daß man sich dran schneiden kann. Natürlich kann man stattdessen auch mit dem Plastiklöffel essen...
Peter II schrieb: > da schon malloc einen void zurück liefert, kann man wohl kaum auf void > verzichten. Soso. Bei den Abertausenden Geräten, die von mir draußen bei den Kunden sind, findet sich nicht ein einziger void Pointer. Also schreib keinen Unsinn. Man kann sehr wohl auf void Pointer verzichten und man sollte das auch tun. Ein Ähnliches gilt für die möglichst sparsame Verwendung von Typecasts. Es nervt, hier immer wieder Beiträge von Leuten lesen zu müssen, die da meinen, daß sie sich auf einem µC ganz genauso benehmen können, wie es ihnen das Lehrbuch über C mal beigebracht hat und dabei Alles und Jedes auch unbedingt verwenden wollen, was die Sprachdefinition nicht ausdrücklich verbietet. Siehe "ich möchte einer Funktion in C einen Pointer übergeben, völlig unabhängig vom Typen" - fragt hier denn keiner, warum eigentlich der TO auf einen solchen Gedanken gekommen ist, wo er doch offensichtlich noch ausgesprochen ahnungslos ist: "ich verstehe die Funktionsweise allerdings nicht". Ja, eben. Mein rat: Bleibenlassen und zwar komplettiko. Stattdessen den Funktionen ordentliche Argumente übergeben, wo der Compiler wenigstens ne Restchance hat, die allegrößten Schnitzer zu erkennen und zu meckern. W.S.
W.S. schrieb: > Soso. Bei den Abertausenden Geräten, die von mir draußen bei den Kunden > sind, findet sich nicht ein einziger void Pointer. Also schreib keinen > Unsinn. Man kann sehr wohl auf void Pointer verzichten und man sollte > das auch tun. warum sollte man auf Funktion der Standard lib verzichten? Du erfindest also das Rads jedes mal neu? qsort hat void* Parameter. Klar wenn man auf alles verzichtet, braucht man kein void* - auch bei ASM braucht man es nicht.
W.S. schrieb: > Bei den Abertausenden Geräten, die von mir draußen bei den Kunden sind, > findet sich nicht ein einziger void Pointer. Nicht jeder muss das C-Subset verwenden, mit dem Du Dich offenbar eingerichtet hat.
W.S. schrieb: > Stattdessen den Funktionen > ordentliche Argumente übergeben, wo der Compiler wenigstens ne > Restchance hat, die allegrößten Schnitzer zu erkennen und zu meckern. Stimmt natürlich aber man benutzt void Pointer ja auch nicht wenn stattdessen ein einfacher int Pointer gereicht hätte. Meistens will man eine Funktion verallgemeinern für verschiedene Datentypen. Und da C keine Templates hat und Makros auch ziemlich gruselig sind bleibt eigentlich nur der void Pointer.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.