Forum: Mikrocontroller und Digitale Elektronik Welchen Sinn hat const void *


von noob (Gast)


Lesenswert?

Hallo!

Eine Funktion hat den Rückgabetyp const void *.

const ist ja ein read-only pointer. Aber ohne Typ? Auf nichts?


Welcher Sinn ergibt sich hierbei?

THX!

von (prx) A. K. (prx)


Lesenswert?

noob schrieb:

> Eine Funktion hat den Rückgabetyp const void *.
> const ist ja ein read-only pointer.

Nö. Das ist ein variabler Pointer auf eine Konstante.

von noob (Gast)


Lesenswert?

ich dachte immer void stünde für "nichts" also hierbei für typenlos....

von Simon K. (simon) Benutzerseite


Lesenswert?

Schon. Aber void* ist nicht gleich void.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

In C++ ist das so, aber in C ist so ein Pointer legal jedem anderen 
Pointertypen zuweisbar, sieh Dir mal an, wie malloc deklariert wird.

von Rolf Magnus (Gast)


Lesenswert?

noob schrieb:
> Hallo!
>
> Eine Funktion hat den Rückgabetyp const void *.
>
> const ist ja ein read-only pointer. Aber ohne Typ? Auf nichts?
>
>
> Welcher Sinn ergibt sich hierbei?

Man sieht gleich, daß man das Objekt nicht ändern soll, auch nicht nach 
Umcasten in den richtigen Typ. Bei C-Style-Casts kommt ggf. eine 
Compiler-Warnung, wenn man das const einfach so wegcastet, in C++ bei 
den moderneren Casts gibt's ohne zusätzlichen const_cast einen Fehler.

von Hans-Georg L. (h-g-l)


Lesenswert?

Der Pointer selbst ist ja definiert, er zeigt nur auf etwas 
unbestimmtes.

Alle Pointer sind gleich gross, deshalb kann der Compiler Speicher dafür 
reservieren.

von noob (Gast)


Lesenswert?

alle pointer sind gleich groß? Ist das deshalb, weil die 
Speicheraddressierung immer die gleiche Größe erfordert? Ist das mit der 
Architektur verheiratet? z.B. AVR 8-Bit RISC?

von Historiker (Gast)


Lesenswert?

noob schrieb:
> alle pointer sind gleich groß? Ist das deshalb, weil die
> Speicheraddressierung immer die gleiche Größe erfordert? Ist das mit der
> Architektur verheiratet? z.B. AVR 8-Bit RISC?

Der Adreßraum eines Pointers muß mindestens so groß sein, wie der 
zugeordnete Speicherraum. Ansonsten wird letzterer (zusammen)gefaltet. 
Alternativ kann der Adreßraum segmentiert werden.
Klassisches Beispiel: X86 - im Ursprung ein 16-Bit-System mit 20 Bit 
Adreßraum, 16 Bit Pointern und 16 Bit Segmenten.

4 Bit wäre die Mindestgröße für die Segment-Werte gewesen - da diese 
größer waren, kam es zu einer "Faltung der besonderen Art" - Stichwort 
A20-Gate.

;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hans-georg Lehnard schrieb:
> Alle Pointer sind gleich gross

Genauer: alle Objektzeiger sind gleich groß, daher können sie in
"void *" und zurück gewandelt werden.

Funktionszeiger sind nicht notwendig genauso groß wie Objektzeiger,
und eine Wandlung eines Funktionszeigers in "void *" und von da
zurück ist durch den C-Standard nicht gedeckt.  Man kann aber einen
Funktionszeiger in einen beliebigen anderen Funktionszeiger und aus
diesem wieder in den originalen wandeln, sodass man einen Typen wie
den folgenden als generischen Funktionszeiger (also als "Platzhalter")
benutzen kann:
1
typedef void (*generic_func_t)(void);

von Hans-Georg L. (h-g-l)


Lesenswert?

Historiker schrieb:
> noob schrieb:
>> alle pointer sind gleich groß? Ist das deshalb, weil die
>> Speicheraddressierung immer die gleiche Größe erfordert? Ist das mit der
>> Architektur verheiratet? z.B. AVR 8-Bit RISC?
>
> Der Adreßraum eines Pointers muß mindestens so groß sein, wie der
> zugeordnete Speicherraum. Ansonsten wird letzterer (zusammen)gefaltet.
> Alternativ kann der Adreßraum segmentiert werden.
> Klassisches Beispiel: X86 - im Ursprung ein 16-Bit-System mit 20 Bit
> Adreßraum, 16 Bit Pointern und 16 Bit Segmenten.
>
> 4 Bit wäre die Mindestgröße für die Segment-Werte gewesen - da diese
> größer waren, kam es zu einer "Faltung der besonderen Art" - Stichwort
> A20-Gate.
>
> ;-)

Die absolute Anzahl Bytes, die ein Pointer belegt sowie die Berechnung 
der endgültigen Speicheraddresse (Flat oder Index) ist Hardware und 
Compiler abhängig. Aber während dem Compilieren ändert sich die Hardware 
nur selten ;)

Jörg Wunsch schrieb:
> Hans-georg Lehnard schrieb:
>> Alle Pointer sind gleich gross
>
> Genauer: alle Objektzeiger sind gleich groß, daher können sie in
> "void *" und zurück gewandelt werden.
>
> Funktionszeiger sind nicht notwendig genauso groß wie Objektzeiger,
> und eine Wandlung eines Funktionszeigers in "void *" und von da
> zurück ist durch den C-Standard nicht gedeckt.  Man kann aber einen
> Funktionszeiger in einen beliebigen anderen Funktionszeiger und aus
> diesem wieder in den originalen wandeln, sodass man einen Typen wie
> den folgenden als generischen Funktionszeiger (also als "Platzhalter")
> benutzen kann:
> typedef void (*generic_func_t)(void);

Richtig und volständigerweise gibts noch anzumerken, das near und far 
pointer auch nicht gleich groß sind ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hans-georg Lehnard schrieb:
> Richtig und volständigerweise gibts noch anzumerken, das near und far
> pointer auch nicht gleich groß sind ;)

Die gibt's aber auch nicht im C-Standard ...

von (prx) A. K. (prx)


Lesenswert?

Jörg Wunsch schrieb:

> Die gibt's aber auch nicht im C-Standard ...

Steht irgendwo im C Standard drin, dass alle Pointer für alle Datentypen 
gleich gross zu sein haben? Es ergibt sich nur aus der Logik der Sache, 
dass "void *" mindestens so gross sein muss wie der grösste davon.

Bei einer wortadressierenden Maschine könnte das beispielsweise 
passieren. Die sind zwar nicht mehr so populär, aber es gibt sie.

Würde ohnehin gerne den O-Ton des Entwicklers eines C Compilers für 
MaxQ2000 hören - ich vermute, dass er über den Erfinder der Architektur 
wenig schmeichelhafte Worte fand. Datenadressraum hat 64K Worte = 128K 
Bytes, aber nur die ersten 64K sind als Bytes adressierbar. Bei der 
Kiste bräuchte man genau genommen 17 Bits für "void *" und 16 Bits für 
"char/int *".

von Rolf Magnus (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Hans-georg Lehnard schrieb:
>> Alle Pointer sind gleich gross
>
> Genauer: alle Objektzeiger sind gleich groß,

Müssen sie nicht zwingend sein.

> daher können sie in "void *" und zurück gewandelt werden.

Dazu müssen sie nicht alle gleich groß sein. Es muß nur sichergestellt 
sein, daß ein void* jede mögliche Objektadresse aufnehmen kann.

> Funktionszeiger sind nicht notwendig genauso groß wie Objektzeiger,
> und eine Wandlung eines Funktionszeigers in "void *" und von da
> zurück ist durch den C-Standard nicht gedeckt.

Eine Konvertierung zwischen Funktionszeiger und Objektzeiger ist in C 
eigentlich gar nicht erlaubt, auch wenn die meisten Compiler es trotzdem 
akzeptieren.

>  Man kann aber einen Funktionszeiger in einen beliebigen anderen
> Funktionszeiger und aus diesem wieder in den originalen wandeln,

War das wirklich ein beliebiger anderer? Ich dachte, es gilt nur für 
void(*)(void).

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.