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!
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.
ich dachte immer void stünde für "nichts" also hierbei für typenlos....
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.
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.
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.
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?
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. ;-)
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); |
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 ;)
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 ...
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 *".
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.