Comment se débarrasser de la conversion 'dépréciée de la constante de chaîne à' char*’ avertissements dans GCC?
donc je travaille sur une base de code excessivement large, et récemment mis à jour en gcc 4.3, qui déclenche maintenant cet avertissement:
attention: conversion dépréciée de la constante de chaîne en 'char* '
évidemment, la bonne façon de corriger ceci est de trouver chaque déclaration comme
char *s = "constant string";
ou appel de fonction comme:
void foo(char *s);
foo("constant string");
et faites-les pointeurs const char
. Cependant, cela signifierait toucher 564 fichiers, minimum, ce qui n'est pas une tâche que je souhaite accomplir à ce stade. Le problème en ce moment est que je cours avec -werror
, donc j'ai besoin d'un moyen pour étouffer ces avertissements. Comment puis-je le faire?
23 réponses
je crois que passer -Wno-write-strings
à gcc supprimera cet avertissement.
toute fonction dans laquelle vous passez chaîne de caractères littérales "I am a string literal"
doit utiliser char const *
comme le type au lieu de char*
.
si vous voulez réparer quelque chose, réparez-le correctement.
explication:
vous ne pouvez pas utiliser les caractères littéraux des chaînes pour initialiser les chaînes qui seront modifiées, parce qu'elles sont de type const char*
. Jeter la constance pour les modifier plus tard est comportement non défini , de sorte que vous devez copier vos const char*
chaînes char
par char
dans des char*
chaînes allouées dynamiquement afin de les modifier.
exemple:
#include <iostream>
void print(char* ch);
void print(const char* ch) {
std::cout<<ch;
}
int main() {
print("Hello");
return 0;
}
Check out gcc Diagnostic Pragma support, et la liste de - w w warning options (modifié: nouveau lien vers warning options ).
pour gcc, vous pouvez utiliser les directives #pragma warning
comme expliqué ici .
j'ai eu un problème similaire, je l'ai résolu comme ceci:
#include <string.h>
extern void foo(char* m);
int main() {
// warning: deprecated conversion from string constant to ‘char*’
//foo("Hello");
// no more warning
char msg[] = "Hello";
foo(msg);
}
est-ce une façon appropriée de résoudre ce problème? Je n'ai pas accès à foo
pour l'adapter à accepter const char*
, bien que ce serait une meilleure solution (parce que foo
ne change pas m
).
si c'est une base de code active, vous pouvez toujours vouloir mettre à jour la base de code. Bien sûr, effectuer les changements manuellement n'est pas faisable, mais je crois que ce problème pourrait être résolu une fois pour toutes par une seule commande sed
. Je n'ai pas essayé, même si, pour prendre avec un grain de sel.
find . -exec sed -E -i .backup -n \
-e 's/char\s*\*\s*(\w+)\s*= "/char const* = "/g' {} \;
cela pourrait ne pas trouver tous les endroits (même ne pas tenir compte des appels de fonction), mais il soulagerait le problème et permettrait de effectuer quelques modifications restantes manuellement.
Je ne peux pas utiliser l'interrupteur du compilateur. Alors j'ai tourné ceci:
char *setf = tigetstr("setf");
à ceci:
char *setf = tigetstr((char *)"setf");
Voici comment le faire en ligne dans un fichier, pour que vous n'ayez pas à modifier votre Makefile.
// gets rid of annoying "deprecated conversion from string constant blah blah" warning
#pragma GCC diagnostic ignored "-Wwrite-strings"
Vous pouvez ensuite plus tard...
#pragma GCC diagnostic pop
remplacer
char *str = "hello";
avec
char *str = (char*)"hello";
ou si vous appelez en fonction:
foo("hello");
remplacer par
foo((char*) "hello");
au lieu de:
void foo(char *s);
foo("constant string");
Cela fonctionne:
void foo(const char s[]);
foo("constant string");
en C++, utilisez le const_cast
comme ci-dessous
char* str = const_cast<char*>("Test string");
Test string
est const chaîne. Donc vous pouvez résoudre comme ceci:
char str[] = "Test string";
ou:
const char* str = "Test string";
printf(str);
Ne typecasting de chaîne constante de pointeur de char c'est à dire
char *s = (char *) "constant string";
vous pouvez aussi créer une chaîne de caractères à partir d'une constante de chaîne en appelant strdup()
.
par exemple, ce code génère un avertissement:
putenv("DEBUG=1");
cependant, le code suivant ne fait pas (il fait une copie de la chaîne sur le tas avant de la passer à putenv
):
putenv(strdup("DEBUG=1"));
dans ce cas (et peut-être dans la plupart des autres) éteindre l'avertissement est une mauvaise idée -- c'est là pour une raison. Les autres l'alternative (rendre toutes les chaînes accessibles en écriture par défaut) est potentiellement inefficace.
écoutez ce que le compilateur vous dit!
voir cette situation:
typedef struct tagPyTypeObject
{
PyObject_HEAD;
char *name;
PrintFun print;
AddFun add;
HashFun hash;
} PyTypeObject;
PyTypeObject PyDict_Type=
{
PyObject_HEAD_INIT(&PyType_Type),
"dict",
dict_print,
0,
0
};
regardez le champ Nom, dans gcc il compilera sans avertissement, mais dans g++ il le fera, Je ne sais pas pourquoi.
Dans C++, Remplacer:
char *str = "hello";
avec:
std::string str ("hello");
et si vous voulez la comparer:
str.compare("HALLO");
Je ne comprends pas comment appliquer votre solution: (- kalmanIsAGameChanger
en travaillant avec Arduino Sketch, j'ai eu une fonction à l'origine de mes avertissements.
fonction originale: char StrContains (char *str, char *sfind)
pour arrêter les Avertissements j'ai ajouté le const devant le char * str et le char * sfind.
modifié: charcontains(const char *str, const char *sfind).
tous les avertissements ont disparu.
il suffit d'utiliser l'option-w pour g++
exemple:
g++ -o -o simple.o simple.cpp-lpthread 151920920"
rappelez-vous que cela n'évite pas la dévalorisation mais empêche l'affichage d'un message d'avertissement sur le terminal.
maintenant si vous voulez vraiment éviter la dépréciation utiliser const mot-clé comme ceci:
const char* s="constant string";
pourquoi n'utilisez-vous pas l'option -Wno-deprecated
pour ignorer les messages d'avertissement dépréciés?
la réponse de BlackShift est très utile, et je l'ai utilisée comme:
extern string execute(char* cmd) {
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[256];
std::string result = " ";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
int main(){
char cmd[]="grep -A1 'xml' out1.txt | grep read|awk -F'=' 'BEGIN{sum=0}{sum=sum+$NF}END{print sum}'";
string result=execute(cmd);
int numOfBytes= atoi(result.c_str());
cout<<"Number of bytes = "<<numOfBytes<<endl;
return 0;
}
le problème en ce moment est que je cours avec-Werror
C'est votre vrai problème, IMO. Vous pouvez essayer quelques moyens automatisés de passer de (char *) à (const char*), mais je mettrais de l'argent sur eux non seulement le travail. Vous devrez avoir un homme impliqué au moins un peu de travail. Pour le court terme, il suffit d'ignorer l'avertissement (mais IMO le laisser en marche, ou il ne sera jamais réparé) et juste enlever le-Werror.
merci à tous pour votre aide. Cueillir ici et là vient cette solution. Cela compile propre. N'ai pas testé le code mais. Demain... peut-être...
const char * timeServer[] = { "pool.ntp.org" }; // 0 - Worldwide
#define WHICH_NTP 0 // Which NTP server name to use.
...
sendNTPpacket(const_cast<char*>(timeServer[WHICH_NTP])); // send an NTP packet to a server
...
void sendNTPpacket(char* address) { code }
je sais, il n'y a qu'un seul élément dans le tableau timeServer. Mais il pourrait y en avoir plus. Le reste a été commenté pour l'instant pour sauver la mémoire.
PyTypeObject PyDict_Type=
{ ...
PyTypeObject PyDict_Type=
{
PyObject_HEAD_INIT(&PyType_Type),
"dict",
dict_print,
0,
0
};
regardez le champ Nom, dans gcc il compilera sans avertissement, mais dans g++ il le fera, Je ne sais pas pourquoi.
dans gcc (Compiling C)
,- Wno-write-strings est actif par défaut.
dans g++ (Compiling C++)
-Wwrite-strings est active par défaut
C'est pourquoi il y a un comportement différent.
Pour nous, l'utilisation des macros de Boost_python
génère de tels avertissements.
Nous utilisons donc -Wno-write-strings
pour compiler C++ car nous utilisons toujours -Werror