const char* nach char*



  • @Dimah: ich glaube nicht, dass hier ein COW-Fehler auftritt, da s[0] doch eigentlich bereits als schreibzugriff angesehen werden sollte. und c_str() ist doch nichtmal garantiert der selbe string, da string nicht nullterminiert sein muss, oder wie seh ich das?



  • zumindest gehts mit einem const_cast ---



  • Original erstellt von Mr. N:
    c_str() ist doch nichtmal garantiert der selbe string, da string nicht nullterminiert sein muss, oder wie seh ich das?

    richtig, es muss nicht derselbe speicher sein, aber derselbe string 😉



  • und außerdem: was ist an KPCs idee auszusetzen? wenn du unbedingt ein char* brauchst, ... (selbst schuld, mach es wie KPC)
    statt 256 machst du dann einfach mit new und länge des strings.



  • @davie: Die Frage ist auch die Semantik. (geiles wort, wa?) Verlangt die Funktion char * ist doch offentsichtlich (in a C++ programmers point of view), dass er verändert wird. c_str() kann nun muss aber nicht derselbe speicher sein. KPCs Lösung ist perfekt - solange die Semantik stimmt. Dimahs Lösung hat in meinen Augen jedoch nur ein Problem: der erhaltene Pointer zeigt nicht notwendigerweise auf einen nullterminierten String. WAHRSCHEINLICH aber ist hier das Problem, dass irgendein unsauberer Bibliotheksprogrammierer das const vor char * (oder nach dem char, nach belieben :D) vergessen hat und es hier also weg muss. DANN sollte man auf jeden Fall const_cast einsetzen.



  • ich gehe davon aus, dass jeder bibliotheksprogrammier sauber programmiert, was const angeht zumindest. außer ich kenn ihn persönlich.



  • Dimahs Lösung ist gefährlich.
    denn was wenn std::string als list oder ähnliches implementiert ist?
    seine Lösung wäre bei einem vector perfekt.

    das bringt uns der Lösung des problems schon näher.
    da hier definitiv ein char* gebraucht wird, wäre es uU eine gute Idee gleich vector<char> zu verwenden!

    const cast ist auch käse!
    funktioniert nur dann, wenn Dimahs Lösung auch funktioniert, und dann ist Dimahs Lösung schöner!

    das mit dem vielen umkopieren ist mir persönlich zuwider...



  • vector<char> aber auch nur nach dem defect report o.ä.
    eine andere lösung wäre, eine eigene string klasse zu machen 😉



  • @Davie:

    ich gehe davon aus, dass jeder bibliotheksprogrammier sauber programmiert, was const angeht zumindest. außer ich kenn ihn persönlich.

    ich aber nicht 😃



  • wie du meinst.
    seltsam, jetzt hat mich das forum rausgeschmissen?



  • seltsam...
    naja, wenn du meinst, ein const_cast ist angebracht...
    ich weiß nicht genau, wie das ist, ob ein const_cast alleine schon undefiniertes verhalten erreicht, wenn die zugrunde liegenden Daten wirklich const sind?



  • const_cast führt nur zu undefiniertem verhalten, wenn man auf den entconsteten dingsda schreibend zugreift



  • dann führt aber nie const_cast zu dem undefinierten verhalten

    /edit: sondern nur das dereferenzieren "danach"

    [ Dieser Beitrag wurde am 19.04.2003 um 00:59 Uhr von davie editiert. ]



  • Original erstellt von Mr. N:
    @Dimah: ich glaube nicht, dass hier ein COW-Fehler auftritt, da s[0] doch eigentlich bereits als schreibzugriff angesehen werden sollte. und c_str() ist doch nichtmal garantiert der selbe string, da string nicht nullterminiert sein muss, oder wie seh ich das?

    stimmt beides
    ahja AFIK gabs ne version vom gcc wo das interne char array in std::string nicht immer nullterminiert war

    was ist jetzt besser
    c_str() + const_cast und COW fehler riskieren oder &s[0] und fehlende nullterminierung reskieren

    natürlich kann man beide probleme so lösen

    s[0]; // hoffe das der compilier troz seiteneffekt nicht wegoptimiert
    char * c = const_cast<char*>( s.c_str() );
    

    bzw.

    s.c_str(); // hoffe das der compilier troz seiteneffekt nicht wegoptimiert
    char * c = &s[0];
    

    Original erstellt von Shade Of Mine:
    **Dimahs Lösung ist gefährlich.
    denn was wenn std::string als list oder ähnliches implementiert ist?
    **

    nicht besprechens wert der fall, oder kenns du ein bsp für?



  • Original erstellt von Dimah:
    **was ist jetzt besser
    c_str() + const_cast und COW fehler riskieren oder &s[0] und fehlende nullterminierung reskieren

    natürlich kann man beide probleme so lösen

    s[0]; // hoffe das der compilier troz seiteneffekt nicht wegoptimiert
    char * c = const_cast<char*>( s.c_str() );
    

    bzw.

    s.c_str(); // hoffe das der compilier troz seiteneffekt nicht wegoptimiert
    char * c = &s[0];
    ```**
    

    ich bin ja aus bereits genannten gründen für c_str()+const_cast. schreiben führt hier einfach zu undefiniertem verhalten. aber dessen ist man sich bewusst. der trick mit s[0]; führt immer noch zu undefiniertem verhalten, denn der compiler (bzw. seine lib) kann für c_str() auch eine kopie zurückliefern. die zweite problemlösung jedoch hilft denke ich gar nicht.



  • Original erstellt von Mr. N:
    aber dessen ist man sich bewusst. der trick mit s[0]; führt immer noch zu undefiniertem verhalten, denn der compiler (bzw. seine lib) kann für c_str() auch eine kopie zurückliefern.

    Auf jeden Fall wird er nur selten den Originalstring verändern, denn c_str ist als const festgelegt.



  • @Daniel E.: ich glaube nicht, dass du verstanden hast, was ich meine 🙄



  • @Mr. N: Ich glaube nicht, dass Du verstanden hast, was ich meine...

    Das was Du geschrieben hast war schon richtig. Dimah hat einen Denktfehler gemacht und behauptet, dass durch den Aufruf von s.c_str() der String s nachträglich nullterminiert wird. Dem kann nicht so sein, denn c_str hat keine Erlaubnisse, das Objekt zu verändern (oder dürfen alle Daten des Strings intern als mutable definiert sein?). Diese Einschränkung hattest Du nicht explizit genannt, sondern Du hattest explizit von der Implementierung abhängig gemacht (O-Ton: »er compiler (bzw. seine lib) kann für c_str() auch eine kopie zurückliefern«), dem ich (IMHO zurecht!) ist nicht so; Damit funktioniert Dimahs Lösung nicht. Prinzipiell kann man std::strings nicht eindeutig auf char-Zeichenketten abbilden. Alles klar?



  • und ich habe gemeint, dass c_str eine kopie liefern kann aber nicht muss, er also auf UB sich verlässt


Anmelden zum Antworten