warning: deprecated conversion from string constant to 'char*'



  • Hallo C++ Forum,

    Ich habe eine C++-Programm welches C-bibliotheken aufruft.
    In meinem code habe ich an einigen stellen sowas stehen:

    char      *side   = "L";
    

    Der Compiler gibt mir an jeder stelle obiges warning aus.
    Ich wollte jetzt durch nachlesn aus jedem dieser zuweisungen sowas machen:

    const char * side = "L";
    

    Das geht aber nicht da:
    [code]
    invalid conversion from 'const char*' to 'char*'
    [code]

    Ich weiß dass man evtl. std::string benutzen sollte...allerdings brauche ich doch für die C-Bibs dann char* arrays.

    Wie kann ich das warning beseiteigen oder welche const-variante wäre hier sauer?
    Warum beschwert sich der compiler mit dem warning?

    Danke euch.



  • Deine erste Version ist deprecated, weil eine Stringkonstante einem Pointer zugewiesen wird, der nicht const ist. Die zweite Version ist richtig.

    "invalid conversion..." erhältst du in irgend einem Code, den du hier nicht gezeigt hast. Wahrscheinlich setzt du side irgendwo ein, wo ein char * verlangt wird.

    Wenn du ein char-Array brauchst, musst du auch eins deklarieren:

    char buffer[100];
    

    Stefan.



  • fragerzeichen schrieb:

    Das geht aber nicht da:

    invalid conversion from 'const char*' to 'char*'
    

    Wo tritt dieser Fehler auf? Sicher nicht bei einer der gezeigten Zeilen.

    fragerzeichen schrieb:

    Ich weiß dass man evtl. std::string benutzen sollte...allerdings brauche ich doch für die C-Bibs dann char* arrays.

    Nein, brauchst du eigentlich auch nicht, std::string hat eine Methode c_str() , die dir einen C-kompatiblen, nullterminierten const char* zurückliefert. Probleme hast du nur, wenn du mit sehr altem oder schlecht designten Code hantierst, der char* verlangt, obwohl er nichts verändert.

    Hintergrund für die Gefährlichkeit von Stringliteralen, die über char* angesprochen werden, ist die Veränderbarkeit der einzelnen Zeichen (was undefiniertes Verhalten produziert). Deshalb sollte man nach Möglichkeit Stringliterale immer als const char* speichern.



  • Ok - aber was mache ich wenn die extrerne C-Funktion also die Library-funktion die ich aufrufe eben nur einen char* erwartet? Ich kann ja da nicht einfach einen const char* übergeben...? was tue ich da?



  • fragerzeichen schrieb:

    Ok - aber was mache ich wenn die extrerne C-Funktion also die Library-funktion die ich aufrufe eben nur einen char* erwartet? Ich kann ja da nicht einfach einen const char* übergeben...? was tue ich da?

    Hängt davon ab, was die Funktion macht.
    Wenn sie den string ändern mag, kannst Du keinen Zeiger auf ein String-Literal nehmen. Geht einfach nicht, da das String-Literal im schreibgeschützten Speicher steht und da auch hingehört, zum Beispiel weil der Speicher dann shared und discardable ist oder für's String-Pooling.

    char const* hw="hello world";
    char const* w="world";
    

    wird zu

    char const* hw="hello world";
    char const* w=hw+6;
    

    Bist Du ganz sicher, daß die Funktion den String nur liest, kannst Du das const wegcasten.
    Aber wenn nicht, mußt Du Dir eine Kopie des String-Literals in eigenem Speicher anlegen und mit der Kopie arbeiten.



  • fragerzeichen schrieb:

    Ok - aber was mache ich wenn die extrerne C-Funktion also die Library-funktion die ich aufrufe eben nur einen char* erwartet? Ich kann ja da nicht einfach einen const char* übergeben...? was tue ich da?

    Bist du sicher, dass die Funktion nichts an deinem String verändert? Falls doch, musst du eben einen veränderbaren String übergeben. Um dich nicht um die Speicherverwaltung zu kümmern, wäre std::vector<char> etwas, dann kannst du über &vec[0] auf die einzelnen Elemente zugreifen, als wärs ein C-String (du musst dann halt genügend grosse Länge und Nullterminierung sicherstellen).

    Um was für eine Funktion handelt es sich denn (nicht nur Name, Beschreibung wäre interessant)?



  • Bist Du ganz sicher, daß die Funktion den String nur liest, kannst Du das const wegcasten.

    wie caste ich was weg?

    so?

    const char* side = "L";
    (char*) side;
    

    ?

    es handelt sich um die funktion dlarf aus der Lapack library
    http://icl.cs.utk.edu/projectsfiles/f2j/javadoc/org/netlib/lapack/DLARF.html



  • Besser mit dem spezialisierten Cast, der kann sonst nämlich nichts Böses anstellen:

    const char* side = "L";
    char* evil_side = const_cast<char*>(side);
    

    ⚠ Vorsicht, das lässt dich nur kompilieren! Wenn deine Funktion in den Speicherbereich schreibt, nimmst du undefiniertes Verhalten in Kauf, was Abstürze, nicht nachvollziehbare Fehler und Schlimmeres verursachen kann. Also vergewissere dich, dass nur Lesezugriff erfolgt.



  • naja...das ding ist in fortran geschrieben...

    wäre eine möglihckeit einfach den const cast* in einen char* zu kopieren und den zu übergeben? oder ist das blödsinn?



  • Wie schon vorgeschlagen wurde nimmst du dafür am Besten einen char-Array und übergibst den (wenn man arrays an eine Funktion übergibt, macht der Compiler daraus einen Pointer aufs erste Element).



  • Doku sagt, es ist nur ein Zeichen.
    Dann reicht es,

    char      side[]   = "L";
    

    bzw

    char      side[]   = "R";
    

    zu machen.

    Doku sagt, das Byte wird nur gelesen.
    Dann geht auch const_cast


Anmelden zum Antworten