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?

386
demandé sur stackptr 2008-09-12 22:15:55

23 réponses

je crois que passer -Wno-write-strings à gcc supprimera cet avertissement.

217
répondu DGentry 2011-10-08 00:26:28

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;
}
535
répondu John 2018-10-03 16:42:23

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 .

69
répondu Rob Walker 2017-05-23 11:54:59

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 ).

68
répondu BlackShift 2015-12-22 22:43:01

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.

29
répondu Konrad Rudolph 2008-09-12 18:49:22

Je ne peux pas utiliser l'interrupteur du compilateur. Alors j'ai tourné ceci:

char *setf = tigetstr("setf");

à ceci:

char *setf = tigetstr((char *)"setf");
25
répondu vy32 2009-08-21 02:14:26

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
24
répondu EdH 2011-11-15 17:54:04

remplacer

char *str = "hello";

avec

char *str = (char*)"hello";

ou si vous appelez en fonction:

foo("hello");

remplacer par

foo((char*) "hello");
22
répondu takataka 2015-12-22 22:46:37

au lieu de:

void foo(char *s);
foo("constant string");

Cela fonctionne:

void foo(const char s[]);
foo("constant string");
15
répondu John 2014-10-04 15:28:22

en C++, utilisez le const_cast comme ci-dessous

char* str = const_cast<char*>("Test string");
13
répondu appapurapu 2015-12-22 22:44:13

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);
7
répondu alexsid 2012-09-14 14:19:26

pourquoi ne pas utiliser le moulage par type?

(char*) "test"
5
répondu Dario 2015-12-22 22:44:34

Ne typecasting de chaîne constante de pointeur de char c'est à dire

char *s = (char *) "constant string";
3
répondu tejp124 2015-12-22 22:45:51

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!

2
répondu BillAtHRST 2011-11-09 16:26:46

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.

1
répondu shindow 2011-08-01 08:25:31

Dans C++, Remplacer:

char *str = "hello";

avec:

std::string str ("hello");

et si vous voulez la comparer:

str.compare("HALLO");
1
répondu Sohrab 2017-12-21 12:56:22

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.

1
répondu MyGEARStationcom 2018-03-08 20:03:34

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";  
0
répondu Md. Arafat Al Mahmud 2012-06-08 16:43:11

pourquoi n'utilisez-vous pas l'option -Wno-deprecated pour ignorer les messages d'avertissement dépréciés?

0
répondu Drew Noakes 2013-03-06 22:24:57

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;
    }
0
répondu coder 2013-07-25 10:25:20

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.

0
répondu James Antill 2015-12-30 04:44:03

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.

0
répondu Micheal Morrow 2016-03-05 11:47:49
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

-1
répondu msn 2012-10-22 03:51:50