void* vs. char*



  • icarus2 schrieb:

    Man sollte void * verwenden, um Casts zu vermeiden:

    umgekehrt!
    void* ist gut, um rohe adressen herumzureichen.
    aber wenn man dereferenzieren will, muss man aber doch casten.



  • out of the void schrieb:

    void* ist gut, um rohe adressen herumzureichen.
    aber wenn man dereferenzieren will, muss man aber doch casten.

    Guter Punkt.



  • out of the void schrieb:

    icarus2 schrieb:

    Man sollte void * verwenden, um Casts zu vermeiden:

    umgekehrt!
    void* ist gut, um rohe adressen herumzureichen.
    aber wenn man dereferenzieren will, muss man aber doch casten.

    Damit es auch die ganz doofen verstehen: Man sollte void * verwenden, um Casts bei Funktionsaufrufen zu vermeiden.

    Sollte aus dem Kontext klar sein...



  • Meine Einstellung dazu ist, dass ich diesen Cast an der Stelle mit der Pointer-Arithmetik mache, denn dort muss ich ja sowieso argumentieren, dass das was ich da mache korrekt ist. Ansonsten verschmiere ich doch diesen Knackpunkt bloß auf viele Stellen. Aber ist das ein Argument, das "zählt"? Gibt es da überhaupt eines, das nicht auf bloße Gegenüberstellung der Anzahl der nötigen Casts hinausläuft?



  • Der echte Tim schrieb:

    int * func_doof (void) {
    	int *r = NULL;
    	r = (int *) malloc (100);
    	return r;
    }
    

    das ist besonders doof, wenn er include<stdlib.h> vergessen hat und sizeof(int)!=sizeof(void*) ist jedenfalls vor C11. casts verdecken potentielle fehler.



  • casting show schrieb:

    Der echte Tim schrieb:

    int * func_doof (void) {
    	int *r = NULL;
    	r = (int *) malloc (100);
    	return r;
    }
    

    das ist besonders doof [...]

    Das war genau sein Punkt! 🙄



  • icarus2 schrieb:

    casting show schrieb:

    Der echte Tim schrieb:

    int * func_doof (void) {
    	int *r = NULL;
    	r = (int *) malloc (100);
    	return r;
    }
    

    das ist besonders doof [...]

    Das war genau sein Punkt! 🙄

    der bleibt übrig, denn meinen punkt hast du rausgelöscht. 😉



  • casting show schrieb:

    das ist besonders doof, wenn er include<stdlib.h> vergessen hat und sizeof(int)!=sizeof(void*) ist jedenfalls vor C11. casts verdecken potentielle fehler.

    Das ist imho ein recht konstruiertes Beispiel, bzw. wenn solche Fehler passieren (also das Vergessen elementarer Header), dann ist Hopfen und Malz verloren.

    Meine Argumentation gegenüber den Leuten wäre einfach: Der Standard sieht es so vor, warum also meinen cleverer zu sein bzw. eine Konvention mit Füssen zu treten? Aber gut, ich kann mir die "Argumentation" der Kollegen vorstellen, ... ignore? 😃



  • Der echte Tim schrieb:

    casting show schrieb:

    das ist besonders doof, wenn er include<stdlib.h> vergessen hat und sizeof(int)!=sizeof(void*) ist jedenfalls vor C11. casts verdecken potentielle fehler.

    Das ist imho ein recht konstruiertes Beispiel, bzw. wenn solche Fehler passieren (also das Vergessen elementarer Header), dann ist Hopfen und Malz verloren.

    Hast du Recht. Fast jeder verwendet heute eine IDE, die on-the-fly prüft was einer reinhackt. Vergessene headers werden umgehend angemeckert oder gleich automatisch #included.

    Wer aber als Nostalgiker immer noch VI, Emacs, Notepad, NEdit u.ä. und einen alten Compiler benutzt, der wird oft nicht einmal ein Warning bekommen, wenn er eine Library-Funktion ohne Prototyp aufruft.

    Allgemein sollte man bei Casting sehr vorsichtig sein. Ist jedenfalls meine Meinung.



  • Danke für eure Standpunkte!



  • casting show schrieb:

    sizeof(int)!=sizeof(void*)

    diese bedingung ist nur ganz zufällig auf bestimmten systemen erfüllt.
    allgemein steht da aber äpfel != birnen, weil das eine die adressbreite ist und das andere die anzahl der bytes, die eine variable im speicher belegt.

    RollerCaster schrieb:

    Allgemein sollte man bei Casting sehr vorsichtig sein. Ist jedenfalls meine Meinung.

    ein möglicher grund für void-zeiger wäre z.b. sowas:

    void Zeichenfunktion(void *zeichenobjekt, int objekttyp)
    {
    switch(objekttyp)
    {
    case KREIS:
    ZeichneKreis(zeichenobjekt);
    break;
    case RECHTECK:
    ZeichneRechteck(zeichenobjekt);
    break;
    }
    }
    

    der grund dafür wäre, dass sich das "hauptprogramm" nicht weiter darum zu kümmern braucht, welche funktion aufgerufen werden muss, um die gewünschte figur zu zeichnen, was der übersichtlichkeit wieder zugute kommt.



  • Was soll dieses Geflenne, ob void* oder char*?
    Wenn ein Typ undefiniert ist, dann nimmt man void*, da braucht man nicht zu diskutieren.
    Gut, es mag sein, daß das für einen C-Programmierer schon etwas zu abstrakt ist, aber diese Abstraktion sollte man schon einer Hochsprache zuerkennen. 😉



  • Das ist natürlich Quatsch.
    Erstmal ist void* kein undefinierter Typ sondern ein definierter Typ.
    Und weiterhin ist Sinn und Zweck eines (Daten)Zeigers die Dereferenzierung,
    und da wird bei void* nun mal der originale Ausgangstyp (oder kompatibel) benötigt um type punning und damit UB zu vermeiden.
    Ausschließlich für Zwecke, bei denen der Speicher als rohe Bytefolge verarbeitet werden kann/soll, ist void* ohne Originaltypinfo ohne UB verwendbar, da hierbei mit char/signed char/unsigned char ohne strict aliasing break(d.h. ohne UB) gefahrlos gearbeitet werden kann, da void* genau das gleiche (und beste) Alignment gemäß Standard besitzt wie char/signed char/unsigned char.
    Beispiele sind memcpy,fread,fwrite



  • Wutz schrieb:

    ... da void* genau das gleiche (und beste) Alignment gemäß Standard besitzt wie char/signed char/unsigned char.
    Beispiele sind memcpy,fread,fwrite

    Einn schnelles memcpy schaufelt niemals byteweise, sondern mit den größten Schaufeln, die die CPU zur Verfügung stellt. Einzelne Bytes nur für den Rest, oder wenn weniger gefragt ist. 🙂



  • Du hast keine Ahnung, wovon du redest. Also halt die Klappe.
    Wenn du nicht weißt, was Alignment bedeutet, dann halt die Klappe und zeige nicht öffentlich deine Inkompetenz.
    Wenn du nicht weißt, dass der Standard keinerlei Implementierungsvorschriften für Standardfunktionen vorschreibt, dann halt die Klappe und zeige nicht öffentlich deine Inkompetenz.
    Wenn du nicht weißt, dass das Alignmentproblem naturgemäß immer vor jeglicher konkreter Kopieraktion durch die CPU zuschlägt, dann halt die Klappe und zeige nicht öffentlich deine Inkompetenz.



  • Wutz schrieb:

    ... dass das Alignmentproblem naturgemäß immer vor jeglicher konkreter Kopieraktion durch die CPU zuschlägt
    ...

    Aus diesem Grund muss der Speicher in drei Schritten kopiert werden:

    1. Byteweises Kopieren bis zur Alignment-Grenze,
    2. Turbo einschalten: (DMA, Schleife unter Nutzung voller Registerbreiten, usw.),
    3. Byteweises Kopieren des Rests.

    Die Argumente der memcpy-Funktion bieten alles, was für dafür nötig ist.

    Aber es ist wohl müssig, das einem Informatikstudium-Abbrecher wie dir zu erzählen, der außer Uni-Übungen und privaten Gehversuchen in C diesbezüglich noch nichts geleistet hat.



  • Kritiker1 schrieb:

    Wutz schrieb:

    ... dass das Alignmentproblem naturgemäß immer vor jeglicher konkreter Kopieraktion durch die CPU zuschlägt
    ...

    Aus diesem Grund muss der Speicher in drei Schritten kopiert werden:

    ...

    Aber es ist wohl müssig, das einem Informatikstudium-Abbrecher wie dir zu erzählen, der außer Uni-Übungen und privaten Gehversuchen in C diesbezüglich noch nichts geleistet hat.

    Klingt so, als ob Wutz was anderes behauptet hätte, hat er aber doch nicht?!



  • Dorfdepp.
    Du hast immer noch nichts verstanden.
    Wer lesen kann, ist klar im Vorteil.
    Wenn du mal 25 Jahre Erfahrungen in praktischer C Programmierung haben solltest, kannst du hier mal wieder vorbeischauen - und wirst dann über dein naives Nachgeplapper von aufgeschnapptem Halbwissen nur den Kopf schütteln können.



  • Belli schrieb:

    Klingt so, als ob Wutz was anderes behauptet hätte, hat er aber doch nicht?!

    Er hat viel anderes behauptet. Lies doch einfach mal seinen Beitrag. Ich könnte schwören, dass er jemand ist, der sich tierisch was darauf einbildet, weil er etwas C kann, aber praktisch nie etwas auf die Reihe gebracht hat.



  • Wutz schrieb:

    .
    Wenn du mal 25 Jahre Erfahrungen in praktischer C Programmierung haben solltest ...

    Dann zeig mal bitte deine Referenzen. Ansonsten halte ich dich für einen Faker und Blender. Mehr nicht.

    Ich hoffe, dass ich mich täusche!


Anmelden zum Antworten