C++ verouderde conversie van stringconstante naar ‘char*’

Ik heb een klas met een private char str[256];

en daarvoor heb ik een expliciete constructor:

explicit myClass(const char *func)
{
    strcpy(str,func);
}

Ik noem het als:

myClass obj("example");

Als ik dit compileer krijg ik de volgende waarschuwing:

verouderde conversie van stringconstante naar ‘char*’

Waarom gebeurt dit?


Antwoord 1, autoriteit 100%

Dit is een foutmelding die je ziet wanneer je een situatie als de volgende hebt:

char* pointer_to_nonconst = "string literal";

Waarom? Welnu, C en C++ verschillen in het type letterlijke tekenreeks. In C is het type array van char en in C++ is het een constante array van char. In ieder geval is het niet toegestaan ​​om de karakters van de letterlijke string te veranderen, dus de const in C++ is niet echt een beperking maar meer een soort veiligheidsding. Een conversie van const char* naar char* is om veiligheidsredenen over het algemeen niet mogelijk zonder een expliciete cast. Maar voor achterwaartse compatibiliteit met C staat de taal C++ het nog steeds toe om een ​​letterlijke tekenreeks toe te wijzen aan een char* en geeft je een waarschuwing dat deze conversie wordt afgeschaft.

Dus ergens mis je een of meer consts in je programma voor de juistheid van de const. Maar de code die u ons heeft laten zien, is niet het probleem, omdat deze soort verouderde conversie niet wordt uitgevoerd. De waarschuwing moet ergens anders vandaan zijn gekomen.


Antwoord 2, autoriteit 92%

De waarschuwing:

verouderde conversie van stringconstante naar ‘char*’

wordt gegeven omdat je ergens (niet in de code die je hebt gepost) iets doet als:

void foo(char* str);
foo("hello");

Het probleem is dat je een letterlijke tekenreeks (met type const char[]) probeert te converteren naar char*.

Je kunt een const char[] converteren naar const char* omdat de array vervalt naar de aanwijzer, maar wat je doet is van een veranderlijk een constante maken.

Deze conversie is waarschijnlijk toegestaan ​​voor C-compatibiliteit en geeft u alleen de genoemde waarschuwing.


Antwoord 3, autoriteit 65%

Als antwoordnr. 2 door fnieto – Fernando Nieto beschrijft duidelijk en correct dat deze waarschuwing wordt gegeven omdat je ergens in je code iets doet (niet in de code die je hebt gepost) zoiets als:

void foo(char* str);
foo("hello");

Als u uw code echter ook waarschuwingsvrij wilt houden, breng dan de betreffende wijziging aan in uw code:

void foo(char* str);
foo((char *)"hello");

Dat wil zeggen, cast de constante string naar (char *).


Antwoord 4, autoriteit 28%

Er zijn 3 oplossingen:

Oplossing 1:

const char *x = "foo bar";

Oplossing 2:

char *x = (char *)"foo bar";

Oplossing 3:

char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");

Arrays kunnen ook worden gebruikt in plaats van pointers, omdat een array al een constante pointer is.


Antwoord 5, autoriteit 2%

In feite is een letterlijke tekenreeksconstante noch een const char * noch een char* maar een char[]. Het is nogal vreemd, maar het staat opgeschreven in de c++-specificaties; Als u het wijzigt, is het gedrag niet gedefinieerd omdat de compiler het in het codesegment kan opslaan.


Antwoord 6, autoriteit 2%

Misschien kun je dit proberen:

void foo(const char* str) 
{
    // Do something
}
foo("Hello")

Het werkt voor mij


Antwoord 7, autoriteit 2%

Een reden voor dit probleem (dat nog moeilijker te detecteren is dan het probleem met char* str = "some string" – wat anderen hebben uitgelegd) is wanneer u constexpr.

constexpr char* str = "some string";

Het lijkt erop dat het zich zou gedragen als const char* str, en dus geen waarschuwing zou veroorzaken, zoals het vóór char* voorkomt, maar zich in plaats daarvan gedraagt ​​als char* const str.

Details

Constante aanwijzer en aanwijzer naar een constante. Het verschil tussen const char* str en char* const str kan worden uitgelegd als volgt.

  1. const char* str : Verklaar str als een pointer naar een const char. Dit betekent dat de gegevens waarnaar deze aanwijzer verwijst constant zijn. De aanwijzer kan worden gewijzigd, maar elke poging om de gegevens te wijzigen, zou een compilatiefout veroorzaken.
    1. str++ ; : GELDIG. We passen de aanwijzer aan en niet de gegevens waarnaar wordt verwezen.
    2. *str = 'a'; : ONGELDIG. We proberen de gegevens waarnaar wordt verwezen te wijzigen.
  2. char* const str : Verklaar str als een const-pointer naar char. Dit betekent dat het punt nu constant is, maar de data waarnaar wordt verwezen ook niet. De aanwijzer kan niet worden gewijzigd, maar we kunnen de gegevens wijzigen met behulp van de aanwijzer.
    1. str++ ; : ONGELDIG. We proberen de aanwijzervariabele te wijzigen, die een constante is.
    2. *str = 'a'; : GELDIG. We proberen de gegevens waarnaar wordt verwezen te wijzigen. In ons geval zal dit geen compilatiefout veroorzaken, maar een runtime-fout, omdat de string hoogstwaarschijnlijk in een alleen-lezen-gedeelte van het gecompileerde binaire bestand terechtkomt. Deze verklaring zou logisch zijn als we dynamisch geheugen hadden toegewezen, bijv. char* const str = new char[5];.
  3. const char* const str : Verklaar str als een const-pointer naar een const char. In dit geval kunnen we de aanwijzer, noch de gegevens waarnaar wordt verwezen, wijzigen.
    1. str++ ; : ONGELDIG. We proberen de aanwijzervariabele te wijzigen, die een constante is.
    2. *str = 'a'; : ONGELDIG. We proberen de gegevens waarnaar deze aanwijzer verwijst, die ook constant is, te wijzigen.

In mijn geval was het probleem dat ik verwachtte dat constexpr char* str zich zou gedragen als const char* str, en niet char* const str, omdat het visueel dichter bij het eerste lijkt.

Ook de waarschuwing die wordt gegenereerd voor constexpr char* str = "some string" verschilt enigszins van char* str = "some string".

  1. Compilerwaarschuwing voor constexpr char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *const'
  2. Compilerwaarschuwing voor char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *'.

Tip

U kunt C gibberish – English converter gebruiken om C-declaraties om te zetten in gemakkelijk te begrijpen Engels verklaringen, en omgekeerd. Dit is een C-tool en ondersteunt dus geen dingen (zoals constexpr) die exclusief zijn voor C++.


Antwoord 8

Ik los dit probleem op door deze macro ergens aan het begin van de code toe te voegen. Of voeg het toe in <iostream>, hehe.

 #define C_TEXT( text ) ((char*)std::string( text ).c_str())

Antwoord 9

Ik heb ook hetzelfde probleem. En wat ik eenvoudig deed, is gewoon const char* toevoegen in plaats van char*. En het probleem is opgelost. Zoals anderen hierboven hebben vermeld, is het een compatibele fout. C behandelt strings als char-arrays, terwijl C++ ze behandelt als const char-arrays.


Antwoord 10

Voor wat het waard is, ik vind deze eenvoudige wrapper-klasse nuttig voor het converteren van C++-tekenreeksen naar char *:

class StringWrapper {
    std::vector<char> vec;
public:
    StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
    }
    char *getChars() {
        return &vec[0];
    }
};

Antwoord 11

Het volgende illustreert de oplossing, wijs uw string toe aan een variabele pointer naar een constante array van char (een string is een constante pointer naar een constante array van char – plus lengte info):

#include <iostream>
void Swap(const char * & left, const char * & right) {
    const char *const temp = left;
    left = right;
    right = temp;
}
int main() {
    const char * x = "Hello"; // These works because you are making a variable
    const char * y = "World"; // pointer to a constant string
    std::cout << "x = " << x << ", y = " << y << '\n';
    Swap(x, y);
    std::cout << "x = " << x << ", y = " << y << '\n';
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here

1 + sixteen =

Other episodes