C'est très bien comme code, et c'est sur qu'en C++ on ne peut pas le faire, mais quelle en est l'utilité?
C'est très bien comme code, et c'est sur qu'en C++ on ne peut pas le faire, mais quelle en est l'utilité?
Si vous ne trouvez plus rien, cherchez autre chose...
Vous trouverez ici des tutoriels OpenGL moderne.
Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).
non ce n'est meme pas "violer l'encapsulation". C'est jouer avec les optimisations du compilateur.
Le programme affiche:
Arg ! mais alors comment se fait-ce ? de la magie... ? un bug ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Java est un langage sur! Oui, tres sur.
Et non. Juste un "Expert Confirmé Sénior VIP C++" qui vient de découvrir comment marche le compilateur de sun.... bravo !
Explication ?
Quand on utilise plusieur fois une MEME String "statique" (sans faire de new), le compilateur crée un seul objet "commun" pour toute la classe. C'est donc le meme objet qui est utilisée dans les 2 printf() et dans la methode doEvil().
Et la methode doEvil() modifie justement (par reflection vu que c'est le seul moyen) le contenu de l'objet "commun" créé par le compilateur... et donc le 2nd printf() affiche la String modifiée.
Et demain, le sujet du cours sera: "la reflection n'est pas un jouet". Si vous voulez changer le contenu d'une chaine, essayez l'operateur d'affectation "=".![]()
[sans rancune. Et non, je ne posterai pas un exemple pueril d'ecrasement mémoire en C++]
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Essaye en changeant les modes d'optimisation... S'il n'y a pas de bug, le comportement sera le même.
Le programme affiche:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Java est un langage sur! Oui, tres sur.Ni l'un ni l'autre. Un comportement parfaitement spécifié, et absurde. Je préfère nettement celui optenu avec java -Djava.security.manager Surprise.Arg ! mais alors comment se fait-ce ? de la magie... ? un bug ?
Tiens, il y en a un qui m'a l'air d'avoir été éclaboussé par l'huile sur le feu.Et non. Juste un "Expert Confirmé Sénior VIP C++" qui vient de découvrir comment marche le compilateur de sun.... bravo !
Essaye de faire quelque chose d'aussi absurde en restant dans les comportement définis. On peut faire le reproche au C++ d'avoir autant de comportement indéfinis qu'il en a. Pas celui de pouvoir modifier les littéraux, ça génère un crash sur toute plateforme raisonnable.sans rancune. Et non, je ne posterai pas un exemple pueril d'ecrasement mémoire en C++]
Je ne fais pas du codage absurde, meme par plaisir, quelquesoit le langage.
Perso, ce que je trouve "absurde", c'est d'utiliser la reflection pour modifier une variable locale. Je le répete, l'API Reflection n'est pas un jouet. Pas plus que le ClassLoader ou le GarbageCollector.
Moi non plus, je ne suis pas d'accord avec toutes les specs de java. Pour autant je ne critique pas la sécurité de Java simplement parceque le setting par défaut ne fait pas ce que je veux.Un comportement parfaitement spécifié, et absurde. Je préfère nettement celui optenu avec java -Djava.security.manager Surprise.
si "générer un crash sur toute plateforme raisonnable" est le comportement que tu attendais alors d'accord: ne prend pas Java.On peut faire le reproche au C++ d'avoir autant de comportement indéfinis qu'il en a. Pas celui de pouvoir modifier les littéraux, ça génère un crash sur toute plateforme raisonnable.
Hum... plus sérieusement:
Java est un langage orienté objet. Respecter les paradigmes OO, les règles de design OO et les bonnes pratiques du langage est un minimum.
A ma connaissance, la reflection n'est pas vraiment une "bonne pratique" pour modifier une variable locale. (Pas plus que de créer une classe remplie exclusivement de methodes statiques d'ailleurs)
C'est le meme chose en C++. Il y a des règles a respecter.
Maintenant, je ne vois pas bien ou tu veux en venir avec ton exemple:
- Si c'est "montrer que la reflection c'est dangereux", alors oui tu as raison.
- Si c'est "prouver que le C++ n'a pas besoin de la reflection car c'est dangereux", alors là, je trouve qu'il y a des choses nettement plus dangereuses en C++.
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Disons que le gros problème du C++ c'est qu'il demande de maitriser un certain nombre de choses. Souvent les horreurs arrivent dans la phase d'apprentissage, la faute à de mauvaises ressources sur le sujet. On tombe dans un cercle vicieux de gens qui s'enseignent une mauvaise utilisation du langage.
L'apprendre va demander un mimimun d'efforts -- et encore, j'ai vu ici des gens apprendre le langage (le vrai C++98, pas le C avec des classes et des pointeurs bruts à tout va) et arriver à un bon degré de maitrise en assez peu de temps ; il y en a quelques uns qui m'ont sacrément épaté. Et s'imposer des règles (intelligentes) contraignant l'utilisation du langage permet de faire des trucs robustes, sans avoir à se prendre le choux avec la mémoire.
Les choses à comprendre en C++ ? Hum
- RAII et autre gestion des ressources en milieu exceptionnel
- LSP
- sémantique de valeur vs entité
Arrivé là, on commence à faire facilement des choses sympas. Après, ce n'est qu'un langage comme un autre.
Non, cela ne finira effectivement jamais ...Envoyé par leopard261
Ben, disons que quand on est au taqué, il est difficile d'aller plus vite sans changer ses algos.Envoyé par super_navide
Au fait, le C++ va également bientôt être mis à jour. Dans les petits détails, on aura de quoi manipuler des valeurs simplement et transférer simplement la responsabilité de leurs ressources sans payer la taxe de sortie de fonction que l'on paye parfois aujourd'hui. (-> move semantics) => code simple au moins aussi rapide (si ce n'est plus) que ce que l'on a aujourd'hui. Particulièrement utile pour retourner vecteurs, listes, chaines, ... (juste pour dire que l'on aura moyen d'aller encore plus vite sans donner dans les incantations obscures)
(C'est sûr qu'il n'y a pas cette problématique dans un langage ne supportant pas la sémantique de valeur sur les types utilisateurs)
a- que nenni. Le C++ n'est plus le C with classes depuis bien longtemps. Ce que tu dis c'est un peu comme si on disait que la VM du java est super lente et même pas capable de gérer les cycles -- il s'en est passé des choses depuis le Java 1, c'est pareil en C++.
b- new appelle, en plus, un constructeur pour les objets. C'est une opération nécessaire guère différente d'un malloc + init
c- Je suppose que tu fais référence aux fonctions membre non virtuelles (vu le d-) => Tout faux. this est un argument nécessaire que l'on retrouve en C quand on doit appeller une fonction sur une structure.
d- Arg, le coût révé des fonctions virtuelles. C'est un faux problème. Une fonction virtuelle est un moyen de réaliser un branchement en fonction d'un type de donnée ; ce n'est pas une boucle d'oreille que l'on met pour faire beau. Si tu dois évaluer ce coût, alors compare-le à celui d'une série de if, à celui d'un switch, ou à celui d'un appel via d'une table d'indirection. Cela n'a pas de sens de critiquer ce coût hors contexte des problèmes que cette fonctionnalité solutionne.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Le source de la classe String :
Donc, de ce que je comprends, j'ai un membre privé pour tout ce qui n'est pas dans le package java.lang, et je peux quand même le modifier. Pour moi c'est une violation de l'encapsulation, avant même de considérer que le deuxième print affichera la String modifiée.115 /**
116 * Characters which make up the String.
117 * Package access is granted for use by StringBuffer.
118 */
119 final char[] value;
120
121 /**
122 * Holds the number of characters in value. This number is generally
123 * the same as value.length, but can be smaller because substrings and
124 * StringBuffers can share arrays. Package visible for use by trusted code.
125 */
126 final int count;
En gros de manière générale, si je crée une classe ayant un membre privé ou protégé, n'importe quelle classe extérieure y a accès via le package de réflexion ? Désolé si j'ai loupé un épisode.
La surete de Java est presentee comme une garantie contre des attaques malicieuses. Ne pas proteger des entrees en C++, c'est de l'incompetance. Ne pas proteger des litteraux en Java, c'en est aussi ?
Le meme genre de technique permet de passer une chaine a un module, attendre qu'il ait verifie sa validite puis la modifier.
C'est pas la modification de la variable locale qui est etonnante, c'est celle de litteraux.Perso, ce que je trouve "absurde", c'est d'utiliser la reflection pour modifier une variable locale.
Je ne critique pas (tu peux chercher, j'ai pas souvenir d'avoir ecrit que Java etait un mauvais langage: je ne le connais pas assez, je ne l'ai pas utilise assez pour donner un avis global -- mais d'autre part j'ai l'impression qu'au moins 90% des intervenants dans ce fil ne connaissent pas assez les langages sur lesquels ils emettent des opinions pour le faire en connaissance de cause). Ici, j'ai simplement donne un exemple, ailleurs, j'ai indique des faiblesses dans des arguments.Moi non plus, je ne suis pas d'accord avec toutes les specs de java. Pour autant je ne critique pas la sécurité de Java simplement parceque le setting par défaut ne fait pas ce que je veux.
Un crash est preferable chez moi aux comportements silentieusement incorrects. Et la je suis tres serieux et tu vas avoir beaucoup de mal a me convaincre du contraire.si "générer un crash sur toute plateforme raisonnable" est le comportement que tu attendais alors d'accord: ne prend pas Java.![]()
Donner un coup de pied dans certaines certitudes.Maintenant, je ne vois pas bien ou tu veux en venir avec ton exemple
Entièrement d'accord avec ce concept. Comment s'apercevoir que l'on gère sa mémoire de façon incorrecte si le programme ne réagit pas ou réagit bizarrement sur une autre partie du code par la suite?
Excusez-moi, j'oubliais que le java ne permet aucune gestion de la mémoire, ou presque... Le GC, c'est bien, mais quand on leak de la mémoire à cause d'un non déréférencement d'objets (pas facile de faire ça en java, mais déjà fait, donc que l'on ne vienne pas me dire le contraire ==> j'étais pas encore très doué à l'époque), et que l'on mets 3 semaines à comprendre pourquoi le programme s'alourdit de plus en plus à l'exécution, sans avoir d'indication aucune, et sans avoir de moyen de savoir précisément où et pourquoi, ba merci le gain de temps de prog!!!!!
En C++, il est assez facile de se faire un include remplacant les new et delete par des macros qui marqueront les zones mémoires allouées et désallouées, (on appelle un memory leak reports), allouées deux fois de suite, ou désallouées alors qu'elles n'ont pas été allouées auparavant, etc, bref si c'est juste utiliser le java parce que c'est dur de gérer la mémoire en C++, alors repayez vous des cours de programmation, parce que vous n'avez pas trouvé le bon argument...
Et on y va pour la polemique...
Bah voyons... c'est clair que le C et le C++ n'ont rien a voir...
Tu essayes de me convaincre qu'il n'y a pas de runtime engine en C++ ? Dans ce cas, il faudra me montrer le code de la libraire où sont implémentés new/delete, try/catch/exception, dynamic_cast et m'expliquer qui appelle le constructeur des objets globaux....Envoyé par Stroustrup
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Tu sais, c'est exactement pareil que ton expérience de fuite en Java. Tout le monde passe par la case débutant dans ces langages (certains vont migrer vers "pas intéressés", mais c'est une autre histoire). Et dans cet état débutant, il y a beaucoup de code écrit. Un langage qui élimine les risques de dangling pointers, et réduit les fuites, est beaucoup plus débutant friendly. Surtout comparé à un langage auquel gens sont généralement mal formés.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Non. Pour moi ce qui est etonnant c'est qu'un programmeur utilise la reflection pour modifier une variable locale. C'est comme faire un insert d'assembleur dans un programme C++ pour modifier une zone mémoire.
De toutes facon, ca ne m'interesse pas de savoir si un "mauvais" programme Java est plus dangereux qu'un "mauvais" programme C++ sur une echelle ou le crash est preferable à la modification des literraux.![]()
non, vraiment ca ne m'interesse pas.
Ce qui m'interesse nettement plus, c'est de savoir si un "bon" programme Java est qualitativement meilleur qu'un "bon" programme C++. Par exemple en utilisant les attributs qualités du FURPSE (Functionality, Usability, Reliability, Performance, System Maintainability, Evolutivity).
On sait deja que le "P" (Performance) est en faveur du C++. Qu'en est-il du reste ?
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Ouch....
Tu confonds runtime engine et runtime library.
Les runtime library sont linkés en statique si necessaire, te donnant, au final, uniquement du code assembleur simple.
Verifiable facilement sur n'importe quel ordinateur, crée un programme simple, compile le, envoie le sur un autre ordinateur qui ne dispose d'aucune lib/dll speciales, il marche.
Le java, lui, necessite la JVM installé puisque c'est du code "controllé" et non directement executé sur le proc.
Bref, pas de runtime engine en c++ bien sur.....
Pour avoir appris le C avant le java, puis être repassé au C++ pour des raisons professionnelles, je peux te dire que ce n'est pas rendre service au débutant que de ne pas lui apprendre les concepts de gestions de mémoire (base de la programmation)...
A moins bien sûr que le débutant en question se forme seul et comptes rester amateur.
C'est bien connu on apprend mieux dans l'échec que dans la réussite, même si cela n'est pas le but final, tout simplement car dans l'échec, on cherche à comprendre sa bourde, et cela vaut aussi en programmation.
Laisser des débutants faire des bourdes de programmation sans le savoir, ni même sans qu'ils ne s'en rendent compte, ce n'est franchement pas une bonne idée.
Maintenant, il est vrai que le java possède un attrait pour les programmeurs un peu fainéant qui n'ont pas besoin de performance supplémentaire. Dans mon cas, je ne pense pas que programmer en java un serveur censé gérer plus de 5000 clients simultanément (dans le cadre d'un chat 3D) soit une bonne idée.
Quant au FURPSE, tout cela dépend du PROGRAMMEUR, et non du langage de prog... c'est une légende urbaine ça....
Heu... Au contraire je trouve cela bien plus sûr en Java...
Je n'ai pas vraiment d'expérience du C++ mais j'ai fait beaucoup de C, et il n'est pas rare qu'une erreur ait un comportement aléatoire et ne plante pas forcément (en particulier sur un buffer-overflow).
Il n'y a pas vraiment de comportements silencieusement incorrects en Java... mais c'est généralement sanctionné par une exception![]()
Ce n'est pas un problème lié au langage mais une erreur de développement : si je fais un programme C++ avec des allocations sans faire de désallocations j'obtiendrai le même comportement. C'est plus lié à une mauvaise connaissance du langage et de ses mécanismes qu'à des problèmes du langage.
Note qu'avec un outil comme JConsole c'est assez facile à détecter...
La gestion de la mémoire est surtout assez "chiante". Si une gestion fine de la mémoire peut être très importante dans certain type d'application, ce n'est pas forcément le cas pour toutes les applications.
Perso je développe surtout des applications de gestions et des applications web, et mon coeur de métier ne consiste pas à gérer la mémoire octet par octet... mais ce n'est pas pour autant que je n'en m'en soucies pas plus. C'est juste qu'en Java les règles sont un peu différentes : on limite la porté des variables à leurs strictes minimum. Je rage souvent de voir des débutants faire des classes avec 150 attributs afin d'éviter d'avoir des variables locales...
Bien sûr une gestion fine de la mémoire peut être plus performante que l'utilisation d'un GC, mais je reste persuadé que dans bien des cas le GC est bien meilleur qu'une gestion manuelle de la mémoire.
Cela me rappelle un vieux sujet sur le forum Java (que je ne retrouve malheureusement plus) où un membre voulait appeler un programme C depuis Java pour traiter des données car c'était selon lui 10 fois plus rapide qu'en Java. En fait le programme C ne traitait que 10% des données car il plantait à cause d'un buffer-overflow lié à une mauvaise gestion de la mémoire
Bref des erreurs comme cela tu peux en avoir dans tous les langages...
Les litteraux sont simplement optimisé afin de limiter l'espace mémoire. Ta chaine "Java est un langage sur!" est répété trois fois dans le code mais n'est présente qu'une seule fois en mémoire.
Pour moi il n'y a rien de choquant dans le résultat, mais plutôt dans l'utilisation que tu fais de la réflection...
Et comme tu l'a dit toi même cela peut être bloqué par un SecurityManager afin d'éviter que du code "inconnu" (comme un plugin par exemple) ne puisse mettre en péril ton application...
Par contre l'API de réflection apporte vraiment un gros plus à Java et permet vraiment beaucoup de chose sympa
a++
Dans des applis simples, le gc fait le travail ( correctement) a ta place.
Sur des applis critiques, en c++ tu peux choisir tes methodes ( alloc directe ou memory pool), alors que le gc ne te donne pas le choix, limitant tes options possibles pour optimiser la memoire.
Bref, c++ te laisse le choix et la possibilité d'optimiser plus, au prix d'une dev plus longue, comme d'habitude.
Partager