OVH Cloud OVH Cloud

Traduire en C++ ?

44 réponses
Avatar
Pierre Maurette
Bonjour,
J'ai quelques petites fonctions C90, dont je souhaite réutiliser le
code source, éventuellement légèrement modifié (donc pas de mise en
bib).
Faisant largement appel à stdio.h elles sont tout sauf "idiomatiques"
en C++, mais elles sont parfaitement (hum, je l'espère en tous cas)
conformes à la norme de ce langage. Je précise que l'interface
elle-même est C plus que C++. Un exemple:

int AjouteNumLignes(const char nom_in[]
,const char nom_out[]
,const int nbr_caracts
);

Le int de retour est sémantiquement un bool.
Réécririez-vous ces fonctions en vue d'une utilisation en C++, sachant
qu'elles ont été validées par l'usage dans leur version actuelle ?
Quelle serait la raison objective de cette réécriture ?
Pour l'instant, je pense qu'il est possible de réutiliser "as is" ces
fonctions. Eventuellement en modifiant l'interface:

bool AjouteNumLignesCPP(const std::string nom_in
,const std::string nom_out
,const int nbr_caracts
)
{
return (AjouteNumLignesC(nom_in.c_str()
,nom_out.c_str()
,nbr_caracts) != 0);
}

Merci pour vos lumières.
--
Pierre

10 réponses

1 2 3 4 5
Avatar
Fabien LE LEZ
On Wed, 01 Sep 2004 13:05:21 +0200, Andre Heinen
:

J'avoue que je ne vois pas dans quel cas un COW puisse poser
problème.


1- C'est une pessimisation, pas une optimisation, dès que tu utilises
operator[].

exemple :

std::string const s (...);
size_t lng_s= s.size();

std::string copie (s);
for (size_t i=0; i<lng_s; ++i)
{
if (copie[i] != 'h')
{
copie[i]= 'H';
}
}

Une bonne implémentation de COW vérifierait à chaque appel de
operator[] qu'on travaille bien sur une copie complète. A chaque
appel, i.e. même si on ne fait que lire (je crois ;-) ).

Une mauvaise implémentation ne ferait pas cette vérification, et s
serait modifiée -- bien que constante ! Si, si, j'en ai vu...

2- dès qu'on travaille en multithread, COW ne marche plus :
<http://www.gotw.ca/gotw/045.htm>

--
;-)

Avatar
Loïc Joly
Andre Heinen wrote:
On Tue, 31 Aug 2004 20:16:42 -0400, "Michel Michaud"
wrote:


Dans le
cas de std::string, l'optimisation qui permettrait de pouvoir
se passer de la copie (habituellement un comptage de référence
et un COW) est un mauvais choix dans plusieurs contextes et est
de plus en plus éliminée...



J'avoue que je ne vois pas dans quel cas un COW puisse poser
problème. Peux-tu nous donner un exemple?


Dans le cas d'un programme multithreads, c'est à l'utilisateur des
strings de protèger par mutex les strings partagées entre plusieur
threads. Par contre, s'il y a COW, il est possible qu'une représentation
de string soit partagée entre plusieur threads, sans que l'utilisateur
soit au courant. Dans ce cas, c'est donc à l'implémentation de string de
mettre les mutex là où il faut.

Ce qui conduit à devoir passe son temps dans des mutex qui ne servent
pas forcément (genre, parcourir une chaine de 200 caractères fait appel
à 200 opérations de mutex). Tout ça pour gagner dans le cas où l'on
copie une chaine sans la modifier par la suite, cas qui est plutôt rare
quand les gens passent des références constantes... L'équilibre
gain/coût n'est pas forcément en faveur du COW.

--
Loïc


Avatar
kanze
Fabien LE LEZ wrote in message
news:...
On Wed, 01 Sep 2004 13:05:21 +0200, Andre Heinen
:

J'avoue que je ne vois pas dans quel cas un COW puisse poser
problème.


1- C'est une pessimisation, pas une optimisation, dès que tu utilises
operator[].


Ça dépend. Tout ce qu'on peut dire, c'est que l'utilisation de
l'operator[] sur des chaînes non const peut limiter l'optimisation. Dans
la pratique, je crois que c'est moins de problème qu'on le prétend --
les chaînes sur lesquelles on utilise [] ne sont pas les chaînes qu'on
copie par la suite.

exemple :

std::string const s (...);
size_t lng_s= s.size();

std::string copie (s);
for (size_t i=0; i<lng_s; ++i)
{
if (copie[i] != 'h')
{
copie[i]= 'H';
}
}

Une bonne implémentation de COW vérifierait à chaque appel de
operator[] qu'on travaille bien sur une copie complète. A chaque
appel, i.e. même si on ne fait que lire (je crois ;-) ).


Si la chaîne n'est pas const. Dans le code bien écrit, la plupart du
temps, on va appeler une fonction qui construit la chaîne, en le
renvoyant par valeur -- beaucoup de copies, mais pas de [], puis, on
appelle une autre fonction qui fait quelque chose avec la chaîne : là,
la probabilité qu'on utilise le [] ou les itérateurs (qui pose le même
problème) est plutôt grande, mais on a probablement passer la chaîne par
référence const.

Évidemment, ce genre de scénario n'est pas exclusif, mais je crois qu'il
est assez fréquent, et dans ce scénario, il y aurait des cas où COW
apporte. Or qu'il n'a qu'un coût negligible dans les autres cas.

Une mauvaise implémentation ne ferait pas cette vérification, et s
serait modifiée -- bien que constante ! Si, si, j'en ai vu...


Oui, mais tu n'es jamais à l'abri d'une erreur dans le compilateur ou
dans la bibliothèque. Si on veut racconter des horreurs, je pourrais
t'en racconter.

2- dès qu'on travaille en multithread, COW ne marche plus :
<http://www.gotw.ca/gotw/045.htm>


Je crois que tu as mal compris. Il n'y a pas de problème à faire marcher
COW en multithread. Le problème, c'est de le faire marcher sans prendre
un lock à chaque accès, tout en restant 100% conforme. À ma
connaissance, personne n'y est arrivé jusqu'ici sans utiliser une
définition allégée de « thread safety ». (La bibliothèque g++ le fait,
mais leur définition de thread safety exige que l'utilisateur protège
tous les accès par un lock, y compris sur les chaînes constantes.)

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
Loïc Joly wrote in message
news:<ch4c2a$p2g$...
Andre Heinen wrote:
On Tue, 31 Aug 2004 20:16:42 -0400, "Michel Michaud"
wrote:

Dans le cas de std::string, l'optimisation qui permettrait de
pouvoir se passer de la copie (habituellement un comptage de
référence et un COW) est un mauvais choix dans plusieurs contextes
et est de plus en plus éliminée...


J'avoue que je ne vois pas dans quel cas un COW puisse poser
problème. Peux-tu nous donner un exemple?


Dans le cas d'un programme multithreads, c'est à l'utilisateur des
strings de protèger par mutex les strings partagées entre plusieur
threads. Par contre, s'il y a COW, il est possible qu'une
représentation de string soit partagée entre plusieur threads, sans
que l'utilisateur soit au courant. Dans ce cas, c'est donc à
l'implémentation de string de mettre les mutex là où il faut.


Il existe des algorithmes sans lock, en se servant des primitifs du
genre « atomic_increment », qui peuvent être implémentés sur la majeur
partie des machines moderne. En général -- les std::string ont une
spécification assez bizarre qui fait qu'on ne peut pas donner la
garantie standard de Posix avec de tels algorithmes (ou au moins, je
n'ai jamais entendu parler d'une implémentation qui y arrive).

Ce qui conduit à devoir passe son temps dans des mutex qui ne servent
pas forcément (genre, parcourir une chaine de 200 caractères fait
appel à 200 opérations de mutex).


Pas forcement. Même avec Mutex (plutôt que l'algorithme sans Mutex), on
ne prend le lock que quand on obtient l'itérateur, à l'appel de begin()
et de end().

Tout ça pour gagner dans le cas où l'on copie une chaine sans la
modifier par la suite, cas qui est plutôt rare quand les gens passent
des références constantes... L'équilibre gain/coût n'est pas forcément
en faveur du COW.


Pas forcement. Elle n'est pas forcement contre, non plus, surtout que
tout le monde n'a pas besoin du multi-thread.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Loïc Joly
wrote:

Loïc Joly wrote in message
[...]

Ce qui conduit à devoir passe son temps dans des mutex qui ne servent
pas forcément (genre, parcourir une chaine de 200 caractères fait
appel à 200 opérations de mutex).



Pas forcement. Même avec Mutex (plutôt que l'algorithme sans Mutex), on
ne prend le lock que quand on obtient l'itérateur, à l'appel de begin()
et de end().


Oups, j'ai oublié de préciser que je parlais d'une itération avec
operator[]. Et même une implémentation avec quelquechose de type
(atomic_increment) peut avoir un coût non nul.


Tout ça pour gagner dans le cas où l'on copie une chaine sans la
modifier par la suite, cas qui est plutôt rare quand les gens passent
des références constantes... L'équilibre gain/coût n'est pas forcément
en faveur du COW.



Pas forcement. Elle n'est pas forcement contre, non plus, surtout que
tout le monde n'a pas besoin du multi-thread.


Une implémentation qui serait COW dans un environnement single thread et
pas COW dans un multi thread me semblerait pas mal. L'idéal serait bien
entendu que l'utilisateur puisse choisir en fonction de la façon dont il
utilises ses chaines.


--
Loïc


Avatar
Fabien LE LEZ
On Thu, 02 Sep 2004 11:08:14 +0200, Loïc Joly
:

Une implémentation qui serait COW dans un environnement single thread et
pas COW dans un multi thread me semblerait pas mal.


C'est ce que j'allais proposer...

L'idéal serait bien
entendu que l'utilisateur puisse choisir en fonction de la façon dont il
utilises ses chaines.


Yep. Voire même, décider d'activer COW uniquement si le profiler
indique qu'il faut le faire.


--
;-)

Avatar
Michel Michaud
Dans news:, Fabien LE
On Thu, 02 Sep 2004 11:08:14 +0200, Loïc Joly
:

Une implémentation qui serait COW dans un environnement single
thread et pas COW dans un multi thread me semblerait pas mal.


C'est ce que j'allais proposer...


Ça ne change rien au fait que, parfois, COW n'est pas une bonne
solution même dans un environnement sans thread. Dans mon esprit,
COW est surtout très pratique pour ceux qui sont incapables
d'apprendre à mettre const& pour leurs paramètres ! Dans les
autres cas où ce serait utile, une structure comme les « rope »
est normalement bien supérieure...

L'idéal serait bien
entendu que l'utilisateur puisse choisir en fonction de la
façon dont il utilises ses chaines.


Yep. Voire même, décider d'activer COW uniquement si le profiler
indique qu'il faut le faire.


Ce serait alors à faire sur chaque variable et même il faudrait
peut-être changer dynamiquement : string avec COW, sans COW, style rope,
avec optimisation de chaînes courtes, à longueur fixe
paramétrable... :-)

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
kanze
Loïc Joly wrote in message
news:<ch6nlv$hgl$...
wrote:

Loïc Joly wrote in message
[...]


Une implémentation qui serait COW dans un environnement single thread
et pas COW dans un multi thread me semblerait pas mal. L'idéal serait
bien entendu que l'utilisateur puisse choisir en fonction de la façon
dont il utilises ses chaines.


Une implémentation idéale saurait quand la chaîne va être copiée dans
d'autres threads, et s'y adoptera. Malheureusement, cette
implémentation-là, je ne sais pas la faire.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
"Michel Michaud" wrote in message
news:<DqMZc.23349$...
Dans news:, Fabien LE
On Thu, 02 Sep 2004 11:08:14 +0200, Loïc Joly
:

Une implémentation qui serait COW dans un environnement single
thread et pas COW dans un multi thread me semblerait pas mal.


C'est ce que j'allais proposer...


Ça ne change rien au fait que, parfois, COW n'est pas une bonne
solution même dans un environnement sans thread. Dans mon esprit, COW
est surtout très pratique pour ceux qui sont incapables d'apprendre à
mettre const& pour leurs paramètres !


Dans mon ésprit, c'est surtout intéressant pour les gens qui utilisent
des fonctions qui renvoient des chaînes.

Dans les autres cas où ce serait utile, une structure comme les
« rope » est normalement bien supérieure...


Ça, c'est fort possible.

L'idéal serait bien entendu que l'utilisateur puisse choisir en
fonction de la façon dont il utilises ses chaines.


Yep. Voire même, décider d'activer COW uniquement si le profiler
indique qu'il faut le faire.


Ce serait alors à faire sur chaque variable et même il faudrait
peut-être changer dynamiquement : string avec COW, sans COW, style
rope, avec optimisation de chaînes courtes, à longueur fixe
paramétrable... :-)


Je me démande si on pourrait pas faire quelque chose avec des
« policies ». Je ne m'y connais pas assez pour savoir.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Luc Hermitte
wrote in news:d6652001.0409022332.27f27110
@posting.google.com:

[Intérêt du COW]


Dans mon ésprit, c'est surtout intéressant pour les gens qui utilisent
des fonctions qui renvoient des chaînes.


En l'absence de move-semantics, oui.

Ce serait alors à faire sur chaque variable et même il faudrait
peut-être changer dynamiquement : string avec COW, sans COW, style
rope, avec optimisation de chaînes courtes, à longueur fixe
paramétrable... :-)
Je me démande si on pourrait pas faire quelque chose avec des

« policies ». Je ne m'y connais pas assez pour savoir.


Andrei Alexandrescu a bossé sur des chaines cutomisables par polices ->
flex_string
http://www.moderncppdesign.com/code/main.html
Je n'ai pas regardé en détail, mais il semble traiter les cas du COW
justement.


--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>


1 2 3 4 5