wieder mit dem Zeiger



  • Nachtrag:

    Ein kurzer Kommentar aus www.cplusplus.com

    Return Value.
    A pointer to the allocated space.
    The type of this pointer is void*. A type cast to the desired type of data pointer should be performed on this returned pointer in order to be used as an ordinary array of a concrete type.
    If the system could not allocate the requested block of memory or if the size requested was 0 a NULL pointer is returned.

    MfG
    pierre



  • Der Quelltext kompiliert ohne Probleme, mit einem C Compiler.

    KA wie oft ich das jetzt schon erklärt habe... Also:

    1. In C++ wird ein cast benötigt, weil in der Sprache C++ viele implizierte Typumwandlungen abgeschafft wurden. Wenn Du obigen Code mit einem C++ Compiler kompilierst, dann gibt das i.d.R einen Fehler.
    2. In C werden void*-Zeiger implizit umgewandelt. Es wird kein cast benötigt. Aus K&R II:

    Zeiger auf void

    Jeder Zeiger auf ein Objekt darf in den Typ void * umgewandelt werden, ohne daß Informationen verloren gehen. Wenn das Resultat zurück in den ursprünglichen Zeigertyp umgewandelt wird, wird der ursprüngliche Zeigerwert wiederhergestellt. ...

    Das bedeutet jetzt auch, daß void* Zeiger eine _andere Größe_ oder _eine andere interne Repräsentation_ haben können, als andere Datentypen. Und es bedeutet, dass mein Compiler diese Umwandlung vornehmen darf.

    Also: Das Problem ergibt sich, wenn entsprechende include-Anweisungen vergessen wurden, und eine Funktion (malloc) aufgerufen wird, die einen void*-Zeiger liefert. Nachdem aber der Prototyp dieser Funktion nicht bekannt ist, wird ein passender Prototyp angenommen - der Funktionsaufruf liefert die passenden Parameter, als Rückgabewert wird dann int angenommen. Wenn der cast fehlt, gibt's eine Warnung vom Compiler, dass ein int in einen Zeiger gewandelt wird. Damit bekomme ich einen Hinweis auf einen Fehler.

    Wenn ich einen cast verwende, bekomme ich diesen Hinweis nicht!

    Soviel zu meiner "undifferenzierten Äußerungen" ....

    Pfff



  • Und noch eins:

    aus www.dinkumware.com
    The values stored in the object are indeterminate. You can
    safely convert the return value to an object pointer of any type whose size is not greater than size.

    Reicht das als Nachweis?

    MfG
    pierre



  • Original erstellt von <francais>:
    Reicht das als Nachweis?

    Wofür? Dass ein void* gecastet werden muss, wie Du behauptet hast? Oder dafür, dass du das Problem des Castens des von malloc zurückgegebenen Zeigers in C noch immer nicht verstanden hast?

    Letzteres.



  • hi,

    @MFK,@mady,
    die Wahrheit liegt wie immer in der Mitte.

    ad1) Wer benutzt heute schon reine C-Compiler, wenn dann doch zum überwiegenden
    Teil C++-Compiler.

    ad2) Ihr wollt doch nicht obige Referenzen in Frage stellen oder???
    ad 3) Die überwiegende Literatur schlägt vor, aus Sicherheitsgründen ein
    casten zu verwenden.
    Dies meine ich mit einer "differenzierten" bzw. "undifferenzierten" Aussage.

    Bei einem "modernen" (C++-)Compiler gibt es nur Fehlermeldungen, wenn man das
    Casten vergessen hat.

    MfG
    pierre



  • Original erstellt von <francais>:
    **hi,

    @MFK,@mady,
    die Wahrheit liegt wie immer in der Mitte.

    ad1) Wer benutzt heute schon reine C-Compiler, wenn dann doch zum überwiegenden
    Teil C++-Compiler.

    ad2) Ihr wollt doch nicht obige Referenzen in Frage stellen oder???
    ad 3) Die überwiegende Literatur schlägt vor, aus Sicherheitsgründen ein
    casten zu verwenden.
    Dies meine ich mit einer "differenzierten" bzw. "undifferenzierten" Aussage.

    Bei einem "modernen" (C++-)Compiler gibt es nur Fehlermeldungen, wenn man das
    Casten vergessen hat.

    MfG
    pierre**

    Hallo pierre!

    Ich benutze vorwiegend C Compiler. Es gibt noch sehr viele Umgebungen, von ausschließlich C Compiler eingesetzt werden.

    Einen cast kann ich verantworten, wenn
    - Ein C Programm einmal nach C++ portiert werden soll.
    - Der Programmierer genau weiß, was ein cast ist und was er bedeutet!!

    Vielleicht kannst Du mir ein paar Beispiele für 'Literatur' geben in welcher der cast empfohlen wird. Das deckt sich nämliche nicht mit meiner Erfahrung. Die meisten (eigentlich alle) Bücher, die ich in den letzten 10 Jahren zu C gelesen habe und die den cast aus anderen Gründen als die gerade Aufgeführten empfehlen, sind Müll und es ist schade um das Papier, auf dem sie gedruckt sind.

    Natürlich stelle ich die dinkumware-lib-Beschreibung nicht in Frage. Aber ich kann eine Aussage wie 'ein cast ist notwendig' nicht unterstützen. Eigentlich alle C-Experten die ich kenne oder von denen ich Beiträge gelesen habe, verurteilen den cast eines void*-Zeigers ausdrücklich. Ausnahmen habe ich aufgeführt.



  • ups: Nochwas.

    Bei einem "modernen" (C++-)Compiler gibt es nur Fehlermeldungen, wenn man das
    Casten vergessen hat.

    Die meisten modernen C-Compiler geben keine Warnung, wenn der cast nicht "vergessen", und der passende Prototyp aber nicht gefunden wurde.

    [ Dieser Beitrag wurde am 03.01.2003 um 16:02 Uhr von mady editiert. ]



  • Original erstellt von <francais>:
    **hi,

    @MFK,@mady,
    die Wahrheit liegt wie immer in der Mitte.
    **

    in diesem Fall nicht.

    Der einzige Grund warum man einen void* casten kann ist der, dass man C++ kompatibilitaet waren will - aber dann sollte man gleich C++ verwenden!!

    ad1) Wer benutzt heute schon reine C-Compiler, wenn dann doch zum überwiegenden
    Teil C++-Compiler.

    Warum sollte man C mit einem C++ COmpiler verwenden??
    C COmpiler werden zB sehr stark bei mikroprozessoren verwendet - da macht C++ komischerweise keinen Stich.

    ad2) Ihr wollt doch nicht obige Referenzen in Frage stellen oder???

    Ich hoere lieber auf comp.lang.c.moderated und de.comp.lang.c sowie dem K&R

    DAS sind Referenzen auf die man sich verlassen kann - nicht irgendwelche Webseiten.

    Ausserdem sagt Dinkumware nix von casten!

    ad 3) Die überwiegende Literatur schlägt vor, aus Sicherheitsgründen ein
    casten zu verwenden.

    Ja, die meisten Buecher empfehlen auch die conio.h zu benutzen und sagen void main() sei legal und fflush(stdin) flusht stdin.

    Lehrbuecher sind KEINE Referenz!

    Bei einem "modernen" (C++-)Compiler gibt es nur Fehlermeldungen, wenn man das
    Casten vergessen hat.

    Dann bekommst du aber eine am Deckel - malloc in einem C++ Programm - shame on you!

    Bsp:

    int main(void)
    {
      char* p=(char*)malloc(100);
      free(p);
      return 0;
    }
    

    Und leider leider leider, fuehrt dies zu einem Absturz und du kommst und kommst nicht drauf warum...

    laesst man den cast weg - sieht man den fehler und alles ist inordnung!



  • hi,

    wer hat denn gesagt, dass ich malloc() in einem C++-Programm verwende??
    Du kannst aber toll zwischen den zeilen lesen! Du solltest Politiker werden!

    Nein, mal im Ernst. Ich habe nur von einem C++-Compiler gesprochen und dass
    diese in den meisten Schulen und Universitäten verwendet werden.

    Erklär mir doch bitte, bei welchem Compiler dein Programm zu einem Absturz
    führt??

    MfG
    pierre



  • Original erstellt von mady:
    In C++ wird ein cast benötigt, weil in der Sprache C++ viele implizierte Typumwandlungen abgeschafft wurden.

    Welche außer der hier angeführten meinst Du? Ich hätte gesagt, dass das Typenkonzept das gleiche ist, von der bewusst in C eingeführten 'Lücke' abgesehen.

    Vielleicht kannst Du mir ein paar Beispiele für 'Literatur' geben in welcher der cast empfohlen wird.

    Im K&R2 wird er konsequent verwendet ...

    Original erstellt von <francais>:
    Wer benutzt heute schon reine C-Compiler, wenn dann doch zum überwiegenden Teil C++-Compiler.

    Viele (Unix-) Systeme bringen erst mal nur einen C-Compiler mit. Wenn ein C++-Compiler mitgeliefert wird, dann ist er unbrauchbar, weil uralt. Und mal ganz davon abgesehen ist mein C-Compiler _wesentlich_ schneller bei der Übersetztung von C-Programmen, als der C++-Compiler. Kein Wunder, denn die C++-Programmiersprache ist ungleich komplexer als C.



  • Original erstellt von <francais>:
    **hi,

    wer hat denn gesagt, dass ich malloc() in einem C++-Programm verwende??
    Du kannst aber toll zwischen den zeilen lesen! Du solltest Politiker werden!
    **

    Du hast gesagt, dass sich ein C++ Compiler beschwert wenn man nicht castet.
    Darauf habe ich gemeint, wenn du malloc in einem C++ Programm verwendest, bist du selber schuld.
    Denn mit einem C++ COmpiler kann man halt kein C Programmieren.

    Nein, mal im Ernst. Ich habe nur von einem C++-Compiler gesprochen und dass
    diese in den meisten Schulen und Universitäten verwendet werden.

    Ja und? Quasi jeder C++ COmpiler hat auch einen C Modus!
    Entweder C++ ODER C - ein mischding ist kaese.

    Erklär mir doch bitte, bei welchem Compiler dein Programm zu einem Absturz
    führt??

    Auf allen Plattformen wo sizeof int != sizeof char*
    zugegeben - unter windows hast du keine Probleme, aber wenn du irgendwann mal die Plattform wechsest, oder jemand ein Programm von dir portiert - dann kanns nen crash geben, den man nur sehr schwer finden kann!

    und was sind die Vorteile vom casten?



  • Original erstellt von <francais>:
    **...
    Nein, mal im Ernst. Ich habe nur von einem C++-Compiler gesprochen und dass
    diese in den meisten Schulen und Universitäten verwendet werden.

    Erklär mir doch bitte, bei welchem Compiler dein Programm zu einem Absturz
    führt??
    ...**

    Tja ... nur leider heißt dieses Forum 'ANSI C'. Somit geht's hier um C in allen Version K&R-C, C89 und C99. Demnach sprechen wir alle von C-Compilen.

    Das Programm kann abstürzen. Das hängt aber nicht am Compiler, sondern an der Umgebung, in der das Programm ausgeführt wird. Wenn Zeiger anders als gespeichert werden als int-Werte, kann das zu verschiedenen Problemen führen.

    1. Der 'vermeindliche' Zeiger zeigt auf einen ungültigen Speicherbereich
    2. Die Rücksprungadresse von malloc() -> main wird nicht korrekt behandelt, malloc() von einem Zeiger ausgeht, ein int aber 'viel' keiner ist. Damit bleiben 'reste' auf dem Stack liegen. [zugegeben - ein 'gebasteltes' Beispiel - aber denkbar]

    siehe zum ganzen Thema auch: ISO/EIC 9899/1999, 6.3.2.3 Pointers

    [ Dieser Beitrag wurde am 03.01.2003 um 16:40 Uhr von mady editiert. ]



  • Original erstellt von Daniel E.:
    ... Im K&R2 wird er konsequent verwendet ...
    ...

    Aber nicht empfohlen (oder sollte mir das irgendwo entgangen sein).

    Aber nochmal - meine Gründe, wann ein cast OK ist:
    - Der Programmierer kennt sich aus - weiß, was ein cast macht
    - Eine evtl. Portierung nach C++

    Gut - der letzte Punkt ist wohl unwahrscheinlich. Ich geb' Dir aber recht, wenn Deine Bemerkung darauf anspielt, dass das K&R den C-Standard nicht ersetzt.

    [ Dieser Beitrag wurde am 03.01.2003 um 16:39 Uhr von mady editiert. ]



  • Original erstellt von <francais>:
    wer hat denn gesagt, dass ich malloc() in einem C++-Programm verwende??
    Du kannst aber toll zwischen den zeilen lesen! Du solltest Politiker werden!

    Du hast das gesagt. Mit einem C++ Compiler compiliert man nun mal C++ Programme und keine C Programme (oder ist das bei dir anders? kompilierst du auch C++ Programme mit ADA Compilern?)

    **

    Nein, mal im Ernst. Ich habe nur von einem C++-Compiler gesprochen und dass diese in den meisten Schulen und Universitäten verwendet werden.

    **

    Ja, zum compilieren von C++ Programmen, wir reden hier aber von C. Es gibt sehr wohl noch C Compiler und C Programme werden idr. mit C Compilern übersetzt. Deswegen gibt es ja noch 2 unterschiedliche Programmiersprachen! Ich glaub du hast da nicht so viel Ahnung, kann das sein?

    ad 3) Die überwiegende Literatur schlägt vor, aus Sicherheitsgründen ein
    casten zu verwenden.

    Welche Sicherheit? Nenn mir einen Sicherheitsvorteil den das bringt (nenn mir überhaupt einen Vorteil, den das bringen soll), eigentlich sorgt es nur dafür, dass man leicht einen Bug einbauen kann.



  • Original erstellt von Daniel E.:
    Welche außer der hier angeführten meinst Du? Ich hätte gesagt, dass das Typenkonzept das gleiche ist, von der bewusst in C eingeführten 'Lücke' abgesehen.

    Wenn ich mich nicht irre, sollte sizeof('a') == 1 mit C++ sein. Mit C kann dass zwar in einigen Fällen zutreffen, ist aber selten. (Ich weiß dass ich Dir in dieser Beziehung nicht's neues erzähle... *g*)

    zu dem Thema auch interessant: Incompatibilities Between ISO C and ISO C++

    EDIT & OT: In Design und Entwicklung von C++ nennt Stroustrup einige Entwurfsrichtlinien für C++. U.a. sind dort in der Liste aufgeführt: 'Typunterscheidung durch den Linker', 'Typermittlung zur Laufzeit' und anderes. Ich denke, C hat diese Dinge nicht zu bieten...

    [ Dieser Beitrag wurde am 03.01.2003 um 17:00 Uhr von mady editiert. ]



  • hi,
    ich finde es immer nett, wenn einem Leute etwas unter die Schuhe schiebt, was man nicht gesagt hat.

    @kingruedi,
    guter Witz!
    Ich weiß als langjähriger Programmierer + Dozent sehr wohl zwischen C- und C++-Programmen zu unterscheiden.

    Meine Aussage war stets folgende:
    1.
    An den meistn Schulen und Universitäten wird nun mal entweder der C++-Compiler
    von microsoft eingesetzt oder der von borland oder der dev-c++.
    Es wird also auf der Basis von wiindows gearbeitet.

    2. Auch mit diesen Computern kann man C-Programme compilieren.
    3. Wenn man bei diesen Compilern den cast weglässt, führt dies unweigerlich
    zu Abstürzen.
    4. Man muss die Schüler/ Studierenden natürlich auf die Gefahren des Casts
    aufmerksam machen

    MfG



  • Original erstellt von <francais>:
    **hi,
    ...1.
    An den meistn Schulen und Universitäten wird nun mal entweder der C++-Compiler
    von microsoft eingesetzt oder der von borland oder der dev-c++.
    Es wird also auf der Basis von wiindows gearbeitet.

    2. Auch mit diesen Computern kann man C-Programme compilieren.
    3. Wenn man bei diesen Compilern den cast weglässt, führt dies unweigerlich
    zu Abstürzen.
    4. Man muss die Schüler/ Studierenden natürlich auf die Gefahren des Casts
    aufmerksam machen

    MfG**

    *lol* - weder mein Borland-Compiler (bcc32) noch die damit erstellten Programme sind jemals wegen eines fehlenden casts (im kontext dieses threads) abgestürzt. Es ist natürlich ein Unterschied, ob der C++ Compiler im C Mode oder im C++ Mode kompiliert. Sinnvollerweise sollte man C Programme im C Mode übersetzen....



  • @mady,
    ich sprach hauptsächlich vom microsoft bzw. devc++-compiler.
    mfg



  • Den MS-C++Compiler besitze ich nicht. Von einem DevC++ Compiler habe ich noch nie was gehört....

    Wahrscheinlich meinst Du die IDE DevC++ mit dem gnu-c Compiler... Hier gilt das gleiche, was ich bereits zum BCC gesagt habe. C Programme im C mode übersetzen und es gibt keine Probleme ... Ich kann mir nicht vorstellen, dass der MS-VC das anders handhaben sollte. Vielleicht kann das mal jemand prüfen?



  • Original erstellt von mady:
    Wenn ich mich nicht irre, sollte sizeof('a') == 1 mit C++ sein. Mit C kann dass zwar in einigen Fällen zutreffen, ist aber selten.

    Das hat aber nichts mit dem Typensystem zu tun, sondern liegt schlicht und einfach daran, dass 'a' in C ein Literal vom Typ 'int' ist.
    Dass C nicht C++ ist, und dass Inkompatiblilitäten nicht zu knapp sind, ist mir durchaus bewusst, hat aber nicht sehr viel mit meiner Frage zu tun. Falls diese nicht so klar war, nochmal: Wo wird in C eine Typenumwandlung durchgeführt, die es in C++ nicht gibt, von der Konvertierung void* -> anyrealtyp* abgesehen?


Anmelden zum Antworten