Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

deprecated conversion from string constant to 'char*'

4 réponses
Avatar
PasDeSpam
bonsoir,

depuis mon code c++, j'appelle des fonctions C qui reclament comme
arguments des char*:

function("blah_blah");

j'ai un warning logique:

deprecated conversion from string constant to 'char*'

quelle est la façon canonique de regler cela? (avec un std::vector<char>
ca va etre tres lourd).

merci

4 réponses

Avatar
Fabien LE LEZ
On Thu, 8 Oct 2009 23:48:02 +0200, (Bruno Causse):

depuis mon code c++, j'appelle des fonctions C qui reclament comme
arguments des char*:

function("blah_blah");

j'ai un warning logique:

deprecated conversion from string constant to 'char*'




De deux choses l'une :

- S'il est écrit explicitement dans la doc que la fonction ne modifie
pas la chaîne, ça signifie qu'il y a une erreur dans le prototype, qui
devrait être "void fonction (char const*);"

C'est, à ma connaissance, l'unique utilité réelle de const_cast<> :

void encapsule_fonction (char const* s)
{
fonction (const_cast<char*>(s));
}


- Sinon, tu n'as pas d'autre choix que passer par un buffer
intermédiaire (std::vector<char>). Si la fonction peut modifier son
argument, tu ne peux pas passer une chaîne constante, point.
Bien sûr, il convient d'encapsuler la fonction. Si tu as beaucoup de
telles fonctions, tu peux envisager d'utiliser des macros.


Tiens, un exemple marrant : la fonction CreateProcess() de l'API
Win32, qui permet de lancer un exécutable. La liste des arguments est
passée comme deuxième paramètre.
En compilation ANSI, ce paramètre n'est pas modifié. On peut donc
passer une chaîne constante.
En revanche, si tu compiles en mode Unicode, tout à coup, la fonction
peut modifier cette chaîne. Il faut donc lui passer une chaîne non
constante (un buffer).
Avatar
James Kanze
On Oct 9, 1:25 am, Fabien LE LEZ wrote:
On Thu, 8 Oct 2009 23:48:02 +0200, (Bruno Causse):



>depuis mon code c++, j'appelle des fonctions C qui reclament
>comme arguments des char*:



>function("blah_blah");



>j'ai un warning logique:



>deprecated conversion from string constant to 'char*'



De deux choses l'une :



- S'il est écrit explicitement dans la doc que la fonction ne
modifie pas la chaîne, ça signifie qu'il y a une erreur dans
le prototype, qui devrait être "void fonction (char const*);"



C'est, à ma connaissance, l'unique utilité réelle de const_cast<> :



Il y en a d'autres, mais elles concernent en générale le
pointeur this.

void encapsule_fonction (char const* s)
{
fonction (const_cast<char*>(s));
}



- Sinon, tu n'as pas d'autre choix que passer par un buffer
intermédiaire (std::vector<char>).



Formellement, selon C++03. Pratiquement, et dans C++0x, tu peux
créer un string de la taille voulue et passer &s[0] à la
fonction. Dans C++0x, il y aura même une version non-const de
data() pour supporter cette utilisation.

Si la fonction peut modifier son argument, tu ne peux pas
passer une chaîne constante, point. Bien sûr, il convient
d'encapsuler la fonction. Si tu as beaucoup de telles
fonctions, tu peux envisager d'utiliser des macros.



Pourquoi des macros, et non des fonctions inline ? (Ou est-ce
que tu voulais dire des macros pour générer les implémentations
de ces fonctions ?)

Tiens, un exemple marrant : la fonction CreateProcess() de
l'API Win32, qui permet de lancer un exécutable. La liste des
arguments est passée comme deuxième paramètre.
En compilation ANSI, ce paramètre n'est pas modifié. On peut
donc passer une chaîne constante.
En revanche, si tu compiles en mode Unicode, tout à coup, la
fonction peut modifier cette chaîne. Il faut donc lui passer
une chaîne non constante (un buffer).



Ce qui est une bonne raison pour ne pas compiler en mode
Unicode.

--
James Kanze
Avatar
Fabien LE LEZ
On Fri, 9 Oct 2009 00:09:41 -0700 (PDT), James Kanze
:

Formellement, selon C++03. Pratiquement, et dans C++0x, tu peux
créer un string de la taille voulue et passer &s[0] à la
fonction.



Disons qu'il faudra un buffer de toute façon. Ici, utiliser
std::string à la place de std::vector<char> n'apporte pas grand-chose.

(Ou est-ce
que tu voulais dire des macros pour générer les implémentations
de ces fonctions ?)



Oui, c'est bien ce que je voulais dire.

En revanche, si tu compiles en mode Unicode, tout à coup, la
fonction peut modifier cette chaîne. Il faut donc lui passer
une chaîne non constante (un buffer).



Ce qui est une bonne raison pour ne pas compiler en mode
Unicode.



Il y a toutefois une bonne raison, bien plus importante, de compiler
en mode Unicode sous Windows : tu peux ouvrir n'importe quel fichier.
J'ai encore pas mal de logiciels sur mon PC, qui sont compilés en
"ANSI", et sont incapables d'ouvrir un fichier dès que son nom
contient des caractères non-ISO-Latin-1.
Avatar
James Kanze
On Oct 9, 6:21 pm, Fabien LE LEZ wrote:
On Fri, 9 Oct 2009 00:09:41 -0700 (PDT), James Kanze
:



>Formellement, selon C++03. Pratiquement, et dans C++0x, tu peux
>créer un string de la taille voulue et passer &s[0] à la
>fonction.



Disons qu'il faudra un buffer de toute façon. Ici, utiliser
std::string à la place de std::vector<char> n'apporte pas
grand-chose.



Si tu veux utiliser le résultat comme std::string, si. Il
t'évite une copie supplémentaire. Plus généralement, si tu
conçois la fonction comme une fonction qui traite du texte,
std::string est en quelque sort plus naturel.

--
James Kanze