Le pub des programmeurs
- 1 927 réponses
- 117 participants
- 123 967 vues
- 130 followers
Anonyme
Wolfen
Question : en quelques mots, c'est quoi les pointeurs intelligents, à quoi ça sert ?
Développeur de Musical Entropy | Nouveau plug-in freeware, The Great Escape | Soundcloud
Pov Gabou
L'idee de base, c'est qu'en C++, le compilateur appelle le destructeur pour toi :
Citation :
class A {
public:
A() { cout << "bou ctor An"}
~A() { cout << "bou dtor An"}
};
Si apres tu fais dans une fonction:
Citation :
int foo(void)
{
A a();
}
Le compilateur va automatiquement appeler ~A() a la fin de foo. L'idee fondamentale avec les pointeurs intelligents, c'est d'utilier cette technique avec l'allocation dynamique. Normalement, quand tu utilises l'allocation dynamique "a la C", tu as quelque chose du genre:
Citation :
int foo(void)
{
A* a;
a = new A();
// code avec a
}
Et hop, la, le compilateur n'appelle PAS ~A() pour toi: t'as une fuite memoire. Tu dois faire
Citation :
int foo(void)
{
A* a;
a = new A();
// code avec a
// on utilise plus a
delete a;
}
Le code au dessus , a la C, est super sujet a erreur. Si le code est simple, ok, ca marche. Maintenant, le plus souvent, tu vas appeler d'autres fonctions a l'interieur, qui vont peut etre generer des erreurs: tu vas avoir des "code path" ou dele a ne sera pas appele. L'exemple typique, c'est une exception dans foo.
L'idee, c'est qu'au lieu de faire un appel a new, tu encapsules le pointer a dans une classe Blop pour que le compilateur :
Citation :
Blop<T> {
public:
Blop <T> (T* ptr) { ptr = new T()};
~Blop <T> ( delete ptr);
}
Maintenant tu fais
Citation :
int foo(void)
{
Blop<A> a();
// code avec a
// on utilise plus a
}
Comme a est un *objet*, de type Blop<A>, cree sur la pile, le compilateur va automatiquement appeler ~Blop, qui wrappe l'appel au destructeur. En gros, avec ce type de technique, tu passes le contrat: la fonction foo "possedde" a, et c'est sa responsabilite de detruire a quand foo retourne a la fin de son execution, quoi qu'il arrive.
Avec new, le contrat c'est: je sais ce que je fais, je detruirai moi meme a, ce qui veut dire qu'il faut penser a tous les cas qui peuvent arriver a l'interieur de foo, et dans chaque detruire a.
Bon, apres, c'est plus complique que ca, il y a les problemes de copies, etc... (mon code C++ ne compilera certainement pas, et ne marchera de toute facon pas, ca fait longtemps que je fais plus de C++, j'ai la flemme de verifier la syntaxe).
Avec les tableaux, c'est pareil: si tu utilises vector<double> a la place de double* a, tu es sur que au niveau memoire, ca va marcher.
Bon, maintenant, ca, c'est la theorie. En pratique, tu as beaucoup de cas problematiques, donc c'est loin d'etre extraordinaire *a mon avis*. Typiquement, les pointeurs intelligents ne gerent que ce qui est connu du compilateur C++. Donc pour les signaux, c'est mort, par exemple.
In fine, j'aime tout autant
Citation :
int foo(void)
{
A *a;
int status;
a = malloc(sizeof(*a));
if (a == NULL) {
goto end;
}
status = do(a);
if (status != 0) {
goto fail_do;
}
return 0;
fail_do:
free(a);
end:
return -1;
}
Puis tu peux pas utiliser le meme type de smart pointer selon que tu utilise un objet, un container stl, etc... Donc si a un moment tu changes dans ton code d'un type a l'autre, il faut pas oublier de changer le type de smart pointer, etc... La syntaxe des template en C++ est extremement mauvaise (la, tout le monde est d'accord en general, mais ca sera peut etre arrange dans le prochain standart. Le pb des template est qu'ils ont ete introduits sans beaucoup de reflexion, comme B. Stroustrup l'a reconnu ::
http://blog.codedread.com/archives/2006/01/03/the-next-c/
)
Bref, fondamentalement, je crois que: "putain mais quand tu fais du code mathematique, c'est deja assez complique de s'assurer que tout marche bien pour devoir se prendre la tete avec des trucs aussi bas niveau. Un systeme de gestion de memoire automatique fait le boulot pour toi, ca marche souvent aussi bien voire mieux, et c'est pas interessant a faire de toute facon".
Les smart pointer C++ les plus utilises sont la:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm
miles1981
Et oui, c'est ça le principe des pointeurs intelligents, et même du paradigme RAII - Ressource Acquisition Is Initialization - ;)
Audio Toolkit: http://www.audio-tk.com/
The Monz
ce boulot de nettoyage pour toi.
Alors, certes, tu es obligé de faire l'allocation de ton objet
Ex: Form A = new Form();
Mais apres, c'est le GC (garbage tralala) qui le gèrera pour toi.. Cela
dit, tu peux implementer aussi le "Dispose" qui peut etre associer au Delete
de C++.
Il est clair que C++ est plus un langage pour informaticien qu'un langage
pour scientifique qui souhaite focaliser (et c'est logique et normal) son
énergie sur l'aspect scientifique de son problème implémenter via l'informatique.
Maintenant, si je prone l'utilisation de C# c'est parce que d'un point
de vue évolution de l'informatique, C++ par rapport à C# c'est comme
l'assembleur par rapport au C++ ou au C...
Si on veut un code ultra rapide, il est clair que C# ne sera pas dans beaucoup de cas le langage le mieux adapté pour la performance... Mets bon,
il est possible dans le langage C# d'utilisé une directive "unsafe" qui fait
que ton code va etre executé en mode "non managé" , donc sans usage du GC et
donc avec un gain de performance énorme.. mais aussi une ouverture au codage
dégueulasse avec erreur sur les pointeurs que ce mode t'autorisera à utiliser.
Pour moi, en tant qu'inge informatique expérimenté, je dirais qu'on est actuellement dans une phase identique à celle qu'on a connu au début des
années 1990, la ou bcp de librairies scientifiques étaient en fortran et que
ce langage commencait à passer la main au C++ ou meme C qui n'avait pas
forcément mis à disposition ces librairies.
Je crois qu'il est essentiel de distinguer dans vos propos concernant les
langages les aspects purement langage, et les aspects librairies...
STL n'a rien à voir avec C++.. C'est juste une librairie que beaucoup de
gens trouvent pratiques.. Mais ce n'est qu'une librairie codé dans un langage...
Un peu comme les gens qui font du java et qui te sortent une quantité
importante de package rendant tel ou tel service. La encore, cela n'a rien
à voir avec le langage mais plutot avec l'environnement logiciel, son framework en quelques sortes fournis avec.
C'est pour cela que je fais une assez forte promotion de C# et du framework .Net (il existe des librairies mathématiques pour .Net) car avec ce framework
on peut davantage se concentrer sur son métier plutot que sur les aspects
purement informatique (cela se fait un peu au détriment des performances).
Mais personnellement, ma société developpe des simulateurs ou la notion de
performance est importante (sans pour autant en etre critique), et l'utilisation de .Net en C# (mais en VB.Net ou autre langage .Net ont aurait les meme performances... sauf peut-etre en C++.Net un poil plus rapide, mais plus abscon en terme de syntaxe) nous satisfait pleinement.
Voila.
THe Monz, Toulouse
miles1981
De plus, ATLAS est toujours encore en Fortran et aucune bibliothèque C ou C++ arrive vraiment à la battre. FFTW est écrit en CaML à la base, donc C/C++ n'a pas vraiment gagné la course aux perfs, on utilise toujours les "vieilles" bibliothèques.
Audio Toolkit: http://www.audio-tk.com/
Anonyme
Dire que C# prends le pas sur le C++ c'est comme les gens qui raconte que java était le nouveau C++. C'est des langages de plus haut niveau. La gestion de la mémoire en C++ c'est pas la pour faire jolie, c'est nécéssaire dans de nombreux cas encore (et ca le restera à priori).
Ensuite effectivement qu'un compilateur C++ sans librairie std c'est pas très utile, mais comme le dis miles, ca fait partie (quasiement?) du langage...
Ensuite faut pas rever non plus, java fait à peine plus que C++, la plupart des librairie externe intéréssante ne sont pas du tout portable (notament pour le multimédia, JMS ou java3D ca marche bien que sous MS ou Mac peut etre, mais le code doit quand meme tenir compte de l'OS).
Ensuite comme l'a dis Gabou, on utilise pas tous ces langages pour la meme chose.
Pov Gabou
Citation :
Cela dit, concernant les pointeurs, en C#, le garbage collector va faire
ce boulot de nettoyage pour toi.
Alors, certes, tu es obligé de faire l'allocation de ton objet
Ex: Form A = new Form();
Mais apres, c'est le GC (garbage tralala) qui le gèrera pour toi.. Cela
dit, tu peux implementer aussi le "Dispose" qui peut etre associer au Delete
de C++.
Tu peux aussi mettre un GC en theorie au C++ (typiquement, boehm), mais j'ai jamais trop essaye.
Citation :
STL n'a rien à voir avec C++.. C'est juste une librairie que beaucoup de
gens trouvent pratiques.. Mais ce n'est qu'une librairie codé dans un langage...
Un peu comme les gens qui font du java et qui te sortent une quantité
importante de package rendant tel ou tel service. La encore, cela n'a rien
à voir avec le langage mais plutot avec l'environnement logiciel, son framework en quelques sortes fournis avec.
Je suis pas d'accord sur la stl n'ayant rien a voir avec le C++: dans les versions recentes du bouquin de reference de Stroustrup, la moitie du bouquin est comparee a ca.
Pour moi, java a gagne "contre" le C++ pour 2 raisons:
- plus de gestion de memoire a la main
- un gros framework disponible partout ou le langage est disponible.
Le 2e point est fondamental: ca veut dire que tout le monde utilisant le langage va utiliser les constructions disponibles. C'est la raison pour laquelle je trouve ca un peu con les gens qui disent "python c'est debile, lisp faisait tout ca il y a 40 ans". Oui, mais lisp, tu fais comment pour acceder au net ? Tu fais comment pour faire du calcul matriciel ? Il y a des librairies, mais pas standart. Comme le C++ qui, en 2006, n'a pas de gestion de threads... Donc std:;list en C++, et les listes en python, c'est pas pareil, parce que tu verras jamais de code python sans listes (ou tres peu), alors que la majorite du code C++ n'utilise meme pas la stl.
Citation :
De plus, ATLAS est toujours encore en Fortran et aucune bibliothèque C ou C++ arrive vraiment à la battre. FFTW est écrit en CaML à la base, donc C/C++ n'a pas vraiment gagné la course aux perfs, on utilise toujours les "vieilles" bibliothèques.
Hmmm... un find . -name '*.f' dans les sources atlas me donnent que des fichiers fortran d'interface ;) ATLAS utilise des kernels en C et en assembleur, et tune les implementations utilisant les kernel tres optimises. Y a rien d'implemente en Fortran. De meme, fftw est ecrit en C (tu verras qu'ils aiment pas le C++;) ), mais la aussi, la generation du code est faite par un autre outil (en effet OCAML).
Citation :
La gestion de la mémoire en C++ c'est pas la pour faire jolie, c'est nécéssaire dans de nombreux cas encore (et ca le restera à priori).
Ca, j'y crois pas par exemple. Pour moi, aujourd'hui, la gestion de memoire, c'est comme l'utilisation de l'assembleur il y a 20 ans. Pour la majorite des applications, c'est pas utile, ou meme impossible de gerer a la main. Pour les OS, oui, ok. Pour le temps reel, embarque, Ok. Pour le reste...
Par exemple, tout le succes de google a la base (techniquement s'entend bien sur), c'est grace a l'utilisation de pc merdiques pour construire un gros centre de calcul. Ca veut dire calcul distribue. Leur systeme est base sur le mapreduce, procede courant en programmation fonctionnelle, dont toutes les implementations a ma connaissance utilisent une gestion de memoire automatique (LISP avec un gc avant que le C soit ne).
Une bonne explication de ce que je veux dire est la:
https://www.joelonsoftware.com/items/2006/08/01.html
Citation :
Ensuite faut pas rever non plus, java fait à peine plus que C++
La gestion de memoire, c'est deja enorme.
Bon, tiens, la, je suis en train de regarder un peu les perfs ublas de boost (la derniere fois que j'avais regarde, c'etait pas encore inclus en standart sous ma distribution linux)... Putain, en tout cas, pour programmer, c'est laborieux.
Wolfen
Développeur de Musical Entropy | Nouveau plug-in freeware, The Great Escape | Soundcloud
Pov Gabou
Bon, comme je connais pas trop ublas, et qu'il y a surement moyen d'ameliorer le code (valgrind me dit quand meme 20000 allocation memoire par iteration !!!!), je pense qu'on peut faire nettement mieux avec ublas (et avec un autre compilo), mais ce sera pas 10 fois plus rapide non plus je pense (peut etre un facteur 2):
python (info donnee par le profiler): 0.027 s par iteration
C++ (g++ version 4.0, flags optim: -O3 -funroll-loops -march=pentium4 -DNDEBUG): 0.03 s
le code est la:
http://www.ar.media.kyoto-u.ac.jp/members/david/ublas/blop.py.html
http://www.ar.media.kyoto-u.ac.jp/members/david/ublas/main.cpp.html
Si j'ai le courage, je regarderai en C demain, mais ca devient penible a faire (quoique je pense pouvoir gagner un bon ordre de grandeur par rapport a ublas qui n'a pas l'air super rapide quand meme).
Anonyme
Citation : Ca, j'y crois pas par exemple. Pour moi, aujourd'hui, la gestion de memoire, c'est comme l'utilisation de l'assembleur il y a 20 ans. Pour la majorite des applications, c'est pas utile, ou meme impossible de gerer a la main. Pour les OS, oui, ok. Pour le temps reel, embarque, Ok. Pour le reste...
Je répète : la gestion de la mémoire en C++ est utile (en conclusion de ce que tu dis donc).
Je répète aussi : on utilise, en général, le langage le plus adapté à ce que l'on veut faire.
Ensuite oui ok la gestion mémoire du java c'est le top, mais ca fait juste du C plus simple. La couche objet est assez légère.
Maintenant je suis d'accord, et encore plus convaincu après ce que tu dis sur le python (ma seule expérience du python m'avais laissé très perplexe, je pensais, encore un langage à la mode).
Sans manipuler de pointeur, peut on par exemple géré "rapidement" (oublions la simplicité) des fusions de graphes, d'automates, etc ?
- < Liste des sujets
- Charte