J'ai une classe avec un private char str[256];
et pour cela j'ai un constructeur explicite:
explicit myClass(const char *func)
{
strcpy(str,func);
}
Je l'appelle comme:
myClass obj("example");
Lorsque je compile ceci, je reçois l'avertissement suivant:
conversion obsolète de la constante de chaîne en 'char *'
Pourquoi cela arrive-t-il?
c++
string
explicit-constructor
mkamthan
la source
la source
strncpy(str, func, 255)
au lieu destrcpy(str, func)
pour une copie plus sûre. Et puis n'oubliez pas d'ajouter le '\ 0' à la fin de la chaîne car strncpy ne l'ajoute pas.Réponses:
Il s'agit d'un message d'erreur que vous voyez chaque fois que vous rencontrez une situation comme celle-ci:
Pourquoi? Eh bien, C et C ++ diffèrent par le type de littéral de chaîne. En C, le type est un tableau de char et en C ++, c'est un tableau constant de char. Dans tous les cas, vous n'êtes pas autorisé à modifier les caractères du littéral de chaîne, donc le const en C ++ n'est pas vraiment une restriction mais plutôt une sécurité de type. Une conversion de
const char*
àchar*
n'est généralement pas possible sans un cast explicite pour des raisons de sécurité. Mais pour la compatibilité descendante avec C, le langage C ++ permet toujours d'attribuer un littéral de chaîne à achar*
et vous avertit que cette conversion est obsolète.Donc, quelque part, il vous manque un ou plusieurs
const
s dans votre programme pour la correction de const. Mais le code que vous nous avez montré n'est pas le problème car il n'effectue pas ce type de conversion obsolète. L'avertissement doit provenir d'un autre endroit.la source
const
duMyClass
constructeur ... puis vous pouvez le résoudre en ajoutant leconst
back.L'avertissement:
est donné parce que vous faites quelque chose comme:
Le problème est que vous essayez de convertir une chaîne littérale (avec type
const char[]
) enchar*
.Vous pouvez convertir un
const char[]
enconst char*
parce que le tableau se désintègre en pointeur, mais ce que vous faites est de faire d'une mutable une constante.Cette conversion est probablement autorisée pour la compatibilité C et vous donne juste l'avertissement mentionné.
la source
Comme réponse non. 2 par fnieto - Fernando Nieto décrit clairement et correctement que cet avertissement est donné parce que quelque part dans votre code vous faites (pas dans le code que vous avez posté) quelque chose comme:
Cependant, si vous souhaitez également garder votre code sans avertissement, effectuez simplement les modifications correspondantes dans votre code:
Autrement dit, lancez simplement la
string
constante sur(char *)
.la source
void foo(char* str)
tel quel? Je pensais que nous ne pouvions pas modifierstr
defoo
toute façon, même le paramètre est écrit comme non-const.Il existe 3 solutions:
Solution 1:
Solution 2:
Solution 3:
Les tableaux peuvent également être utilisés à la place des pointeurs car un tableau est déjà un pointeur constant.
la source
strdup
. Contrairement à votre code, il allouera de l'espace pour le caractère NUL de fin et ne dépassera pas l'allocation.En fait, un littéral de constante de chaîne n'est ni un const char * ni un char * mais un char []. C'est assez étrange mais écrit dans les spécifications c ++; Si vous le modifiez, le comportement n'est pas défini car le compilateur peut le stocker dans le segment de code.
la source
Peut-être que vous pouvez essayer ceci:
Ça marche pour moi
la source
Je résous ce problème en ajoutant cette macro au début du code, quelque part. Ou ajoutez-le
<iostream>
, hehe.la source
C_TEXT
est bien pour un appel de fonction (foo(C_TEXT("foo"));
), mais réclame un comportement indéfini si la valeur est stockée dans une variable commechar *x = C_TEXT("foo");
- toute utilisation dex
(en dehors de l'affectation) est un comportement indéfini car la mémoire vers laquelle elle pointe a été libérée.Une raison de ce problème (qui est encore plus difficile à détecter que le problème avec
char* str = "some string"
- que d'autres ont expliqué) est lorsque vous utilisezconstexpr
.Il semble qu'il se comporterait de la même manière que
const char* str
, et ne provoquerait donc pas d'avertissement, comme auparavantchar*
, mais il se comporte plutôt commechar* const str
.Détails
Pointeur constant et pointeur vers une constante. La différence entre
const char* str
etchar* const str
peut être expliquée comme suit.const char* str
: Déclare str comme pointeur vers un caractère const. Cela signifie que les données vers lesquelles ce pointeur pointe vers lui sont constantes. Le pointeur peut être modifié, mais toute tentative de modification des données lèverait une erreur de compilation.str++ ;
: VALIDE . Nous modifions le pointeur, et non les données pointées.*str = 'a';
: INVALIDE . Nous essayons de modifier les données pointées.char* const str
: Déclare str comme pointeur const vers char. Cela signifie que ce point est désormais constant, mais que les données pointées ne le sont pas non plus. Le pointeur ne peut pas être modifié mais nous pouvons modifier les données à l'aide du pointeur.str++ ;
: INVALIDE . Nous essayons de modifier la variable du pointeur, qui est une constante.*str = 'a';
: VALIDE . Nous essayons de modifier les données pointées. Dans notre cas, cela ne provoquera pas d'erreur de compilation, mais entraînera une erreur d'exécution , car la chaîne sera très probablement placée dans une section en lecture seule du binaire compilé. Cette déclaration aurait du sens si nous avions de la mémoire allouée dynamiquement, par exemple.char* const str = new char[5];
.const char* const str
: Déclare str comme pointeur const vers un caractère const. Dans ce cas, nous ne pouvons ni modifier le pointeur, ni les données pointées.str++ ;
: INVALIDE . Nous essayons de modifier la variable du pointeur, qui est une constante.*str = 'a';
: INVALIDE . Nous essayons de modifier les données pointées par ce pointeur, qui est également constant.Dans mon cas, le problème était que je m'attendais
constexpr char* str
à me comporter commeconst char* str
, et nonchar* const str
, car visuellement, cela semble plus proche du premier.De plus, l'avertissement généré pour
constexpr char* str = "some string"
est légèrement différent dechar* str = "some string"
.constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *'
.Pointe
Vous pouvez utiliser le convertisseur C gibberish ↔ anglais pour convertir les
C
déclarations en déclarations anglaises facilement compréhensibles, et vice versa. C'est unC
outil unique, et donc ne supporte pas les choses (comme constexpr) qui sont exclusives àC++
.la source
J'ai aussi le même problème. Et ce que j'ai simplement fait, c'est simplement ajouter const char * au lieu de char *. Et le problème est résolu. Comme d'autres l'ont mentionné ci-dessus, c'est une erreur compatible. C traite les chaînes comme des tableaux de caractères tandis que C ++ les traite comme des tableaux de caractères const.
la source
Pour ce que cela vaut, je trouve que cette classe wrapper simple est utile pour convertir des chaînes C ++ en
char *
:la source
Ce qui suit illustre la solution, affectez votre chaîne à un pointeur de variable vers un tableau constant de char (une chaîne est un pointeur constant vers un tableau constant de char - plus les informations de longueur):
la source