Le 20/06/2011 14:52, JKB a écrit :Ah, tu vois, finalement, tu es d'accord avec moi. Et dans ce cas,
l'exception n'apporte rien puisque l'intérêt de l'exception est
justement de ne pas gérer les erreurs ligne après ligne.
Code selon JBK :
int writeToFile(char *filename, char *data, int *written) {
File *file = new File();
if ( open(filename, file) != 0 ) {
*written = -1;
return ERROR_UNABLE_TO_OPEN_FILE;
}
int w = 0;
if ( write(file, data, &w) != 0 ) {
*written = -1;
delete file;
return ERROR_UNABLE_TO_WRITE_DATA;
}
*written = w;
delete file;
return 0;
}
Noter :
— les multiples passages par référence parce que la valeur de retour est
déjà occupée par le code d'erreur
— la complexité absurde de la gestion de « written », obligeant à
déclarer une variable locale afin de ne pas affecter une valeur débile
en cas d'erreur
— l'ultra-complexité du nettoyage du « file » temporaire
– la longueur du code
– la duplication du « *written = -1; » ou encore du « delete file; »
Je n'ose trop ajouter le moindre bout de code là-dedans de peur
d'exponentialiser la complexité de la gestion des variables temporaires
(de plus en plus seront à nettoyer au fur et à mesure de la progression
dans la fonction.
À comparer à la même fonction en Java :
int writeToFile(String filename, String data) throw FileException,
IOException {
File file = new File();
try {
// Lancera une FileException en cas d'erreur
open(filename, file);
// Lancera une IOException en cas d'erreur
return write(file, data);
} finally {
file.close();
}
}
2× moins de code, 0 duplication, aucune variable locale bidon, pas de
complexité ni d'imbrication…
Je laisse au lecteur le soin de décider quel code est le plus propre, le
plus réutilisable, le plus maintenable…
Le 20/06/2011 14:52, JKB a écrit :
Ah, tu vois, finalement, tu es d'accord avec moi. Et dans ce cas,
l'exception n'apporte rien puisque l'intérêt de l'exception est
justement de ne pas gérer les erreurs ligne après ligne.
Code selon JBK :
int writeToFile(char *filename, char *data, int *written) {
File *file = new File();
if ( open(filename, file) != 0 ) {
*written = -1;
return ERROR_UNABLE_TO_OPEN_FILE;
}
int w = 0;
if ( write(file, data, &w) != 0 ) {
*written = -1;
delete file;
return ERROR_UNABLE_TO_WRITE_DATA;
}
*written = w;
delete file;
return 0;
}
Noter :
— les multiples passages par référence parce que la valeur de retour est
déjà occupée par le code d'erreur
— la complexité absurde de la gestion de « written », obligeant à
déclarer une variable locale afin de ne pas affecter une valeur débile
en cas d'erreur
— l'ultra-complexité du nettoyage du « file » temporaire
– la longueur du code
– la duplication du « *written = -1; » ou encore du « delete file; »
Je n'ose trop ajouter le moindre bout de code là-dedans de peur
d'exponentialiser la complexité de la gestion des variables temporaires
(de plus en plus seront à nettoyer au fur et à mesure de la progression
dans la fonction.
À comparer à la même fonction en Java :
int writeToFile(String filename, String data) throw FileException,
IOException {
File file = new File();
try {
// Lancera une FileException en cas d'erreur
open(filename, file);
// Lancera une IOException en cas d'erreur
return write(file, data);
} finally {
file.close();
}
}
2× moins de code, 0 duplication, aucune variable locale bidon, pas de
complexité ni d'imbrication…
Je laisse au lecteur le soin de décider quel code est le plus propre, le
plus réutilisable, le plus maintenable…
Le 20/06/2011 14:52, JKB a écrit :Ah, tu vois, finalement, tu es d'accord avec moi. Et dans ce cas,
l'exception n'apporte rien puisque l'intérêt de l'exception est
justement de ne pas gérer les erreurs ligne après ligne.
Code selon JBK :
int writeToFile(char *filename, char *data, int *written) {
File *file = new File();
if ( open(filename, file) != 0 ) {
*written = -1;
return ERROR_UNABLE_TO_OPEN_FILE;
}
int w = 0;
if ( write(file, data, &w) != 0 ) {
*written = -1;
delete file;
return ERROR_UNABLE_TO_WRITE_DATA;
}
*written = w;
delete file;
return 0;
}
Noter :
— les multiples passages par référence parce que la valeur de retour est
déjà occupée par le code d'erreur
— la complexité absurde de la gestion de « written », obligeant à
déclarer une variable locale afin de ne pas affecter une valeur débile
en cas d'erreur
— l'ultra-complexité du nettoyage du « file » temporaire
– la longueur du code
– la duplication du « *written = -1; » ou encore du « delete file; »
Je n'ose trop ajouter le moindre bout de code là-dedans de peur
d'exponentialiser la complexité de la gestion des variables temporaires
(de plus en plus seront à nettoyer au fur et à mesure de la progression
dans la fonction.
À comparer à la même fonction en Java :
int writeToFile(String filename, String data) throw FileException,
IOException {
File file = new File();
try {
// Lancera une FileException en cas d'erreur
open(filename, file);
// Lancera une IOException en cas d'erreur
return write(file, data);
} finally {
file.close();
}
}
2× moins de code, 0 duplication, aucune variable locale bidon, pas de
complexité ni d'imbrication…
Je laisse au lecteur le soin de décider quel code est le plus propre, le
plus réutilisable, le plus maintenable…
À comparer à rien du tout parce que les deux fonctions ne sont pas
identiques puisque ce que tu fais explicitement dans la fonction C
doit être fait explicitement dans l'appelant Java au travers de deux
gestionnaires d'exception.
À comparer à rien du tout parce que les deux fonctions ne sont pas
identiques puisque ce que tu fais explicitement dans la fonction C
doit être fait explicitement dans l'appelant Java au travers de deux
gestionnaires d'exception.
À comparer à rien du tout parce que les deux fonctions ne sont pas
identiques puisque ce que tu fais explicitement dans la fonction C
doit être fait explicitement dans l'appelant Java au travers de deux
gestionnaires d'exception.
Tu peux regarder comment est fichu
Boehm-GC, c'est instructif.
Tu peux regarder comment est fichu
Boehm-GC, c'est instructif.
Tu peux regarder comment est fichu
Boehm-GC, c'est instructif.
Il y a de bonnes raisons de critiquer les GC
Il y a de bonnes raisons de critiquer les GC
Il y a de bonnes raisons de critiquer les GC
Il y en a surtout une qui avantage énormément les GC : les mecs de chez
Sun, Oracle ou IBM sont bien plus compétents que nous pour savoir
comment gérer (proprement si possible) la mémoire.
Et même si vous n'êtes pas d'accord avec ça, vous serez d'accord avec la
contraposée : il est totalement délirant de laisser chaque développeur
gérer sa mémoire.
— le niveau d'une équipe de dev en C est égale à celle de son plus
faible maillon, le reste de l'équipe n'ayant aucun moyen d'éviter et de
contourner les erreurs (visibles ou non) qu'il a pu commettre.
— le niveau d'une équipe de dev en Java est sensiblement égale à celle
de son plus fort maillon, celui-ci aillant toujours la possibilité de
bâtir un code et une architecture ne faisant aucune hypothèse sur la
fiabilité du code réalisé par des devs moins compétents (au pire un gros
try/catch).
Il y en a surtout une qui avantage énormément les GC : les mecs de chez
Sun, Oracle ou IBM sont bien plus compétents que nous pour savoir
comment gérer (proprement si possible) la mémoire.
Et même si vous n'êtes pas d'accord avec ça, vous serez d'accord avec la
contraposée : il est totalement délirant de laisser chaque développeur
gérer sa mémoire.
— le niveau d'une équipe de dev en C est égale à celle de son plus
faible maillon, le reste de l'équipe n'ayant aucun moyen d'éviter et de
contourner les erreurs (visibles ou non) qu'il a pu commettre.
— le niveau d'une équipe de dev en Java est sensiblement égale à celle
de son plus fort maillon, celui-ci aillant toujours la possibilité de
bâtir un code et une architecture ne faisant aucune hypothèse sur la
fiabilité du code réalisé par des devs moins compétents (au pire un gros
try/catch).
Il y en a surtout une qui avantage énormément les GC : les mecs de chez
Sun, Oracle ou IBM sont bien plus compétents que nous pour savoir
comment gérer (proprement si possible) la mémoire.
Et même si vous n'êtes pas d'accord avec ça, vous serez d'accord avec la
contraposée : il est totalement délirant de laisser chaque développeur
gérer sa mémoire.
— le niveau d'une équipe de dev en C est égale à celle de son plus
faible maillon, le reste de l'équipe n'ayant aucun moyen d'éviter et de
contourner les erreurs (visibles ou non) qu'il a pu commettre.
— le niveau d'une équipe de dev en Java est sensiblement égale à celle
de son plus fort maillon, celui-ci aillant toujours la possibilité de
bâtir un code et une architecture ne faisant aucune hypothèse sur la
fiabilité du code réalisé par des devs moins compétents (au pire un gros
try/catch).
Le 20/06/2011 22:15, Nicolas George a écrit :Il y a de bonnes raisons de critiquer les GC
Il y en a surtout une qui avantage énormément les GC : les mecs de chez
Sun, Oracle ou IBM sont bien plus compétents que nous pour savoir
comment gérer (proprement si possible) la mémoire.
Et même si vous n'êtes pas d'accord avec ça, vous serez d'accord avec la
contraposée : il est totalement délirant de laisser chaque développeur
gérer sa mémoire.
Déjà parce que la plupart du temps il ne s'agira pas de sa mémoire mais
de celle de l'appelant, mais en plus il y a fort à parier qu'il n'est
pas ou très peu compétent sur toutes les vraies problématiques de ce
qu'est une gestion au moins correcte sinon propre de la mémoire.
Le problème est donc toujours le même :
— le niveau d'une équipe de dev en C est égale à celle de son plus
faible maillon, le reste de l'équipe n'ayant aucun moyen d'éviter et de
contourner les erreurs (visibles ou non) qu'il a pu commettre.
— le niveau d'une équipe de dev en Java est sensiblement égale à celle
de son plus fort maillon, celui-ci aillant toujours la possibilité de
bâtir un code et une architecture ne faisant aucune hypothèse sur la
fiabilité du code réalisé par des devs moins compétents (au pire un gros
try/catch).
Le 20/06/2011 22:15, Nicolas George a écrit :
Il y a de bonnes raisons de critiquer les GC
Il y en a surtout une qui avantage énormément les GC : les mecs de chez
Sun, Oracle ou IBM sont bien plus compétents que nous pour savoir
comment gérer (proprement si possible) la mémoire.
Et même si vous n'êtes pas d'accord avec ça, vous serez d'accord avec la
contraposée : il est totalement délirant de laisser chaque développeur
gérer sa mémoire.
Déjà parce que la plupart du temps il ne s'agira pas de sa mémoire mais
de celle de l'appelant, mais en plus il y a fort à parier qu'il n'est
pas ou très peu compétent sur toutes les vraies problématiques de ce
qu'est une gestion au moins correcte sinon propre de la mémoire.
Le problème est donc toujours le même :
— le niveau d'une équipe de dev en C est égale à celle de son plus
faible maillon, le reste de l'équipe n'ayant aucun moyen d'éviter et de
contourner les erreurs (visibles ou non) qu'il a pu commettre.
— le niveau d'une équipe de dev en Java est sensiblement égale à celle
de son plus fort maillon, celui-ci aillant toujours la possibilité de
bâtir un code et une architecture ne faisant aucune hypothèse sur la
fiabilité du code réalisé par des devs moins compétents (au pire un gros
try/catch).
Le 20/06/2011 22:15, Nicolas George a écrit :Il y a de bonnes raisons de critiquer les GC
Il y en a surtout une qui avantage énormément les GC : les mecs de chez
Sun, Oracle ou IBM sont bien plus compétents que nous pour savoir
comment gérer (proprement si possible) la mémoire.
Et même si vous n'êtes pas d'accord avec ça, vous serez d'accord avec la
contraposée : il est totalement délirant de laisser chaque développeur
gérer sa mémoire.
Déjà parce que la plupart du temps il ne s'agira pas de sa mémoire mais
de celle de l'appelant, mais en plus il y a fort à parier qu'il n'est
pas ou très peu compétent sur toutes les vraies problématiques de ce
qu'est une gestion au moins correcte sinon propre de la mémoire.
Le problème est donc toujours le même :
— le niveau d'une équipe de dev en C est égale à celle de son plus
faible maillon, le reste de l'équipe n'ayant aucun moyen d'éviter et de
contourner les erreurs (visibles ou non) qu'il a pu commettre.
— le niveau d'une équipe de dev en Java est sensiblement égale à celle
de son plus fort maillon, celui-ci aillant toujours la possibilité de
bâtir un code et une architecture ne faisant aucune hypothèse sur la
fiabilité du code réalisé par des devs moins compétents (au pire un gros
try/catch).
Tu as une drôle de conception de la revue de code. Passons.
Tu as une drôle de conception de la revue de code. Passons.
Tu as une drôle de conception de la revue de code. Passons.
Les exception sont quand même quelque chose de plus élégant et
extensible que le code de retour + errno.
Les exception sont quand même quelque chose de plus élégant et
extensible que le code de retour + errno.
Les exception sont quand même quelque chose de plus élégant et
extensible que le code de retour + errno.
Code selon JBK :
int writeToFile(char *filename, char *data, int *written) {
File *file = new File();
if ( open(filename, file) != 0 ) {
*written = -1;
return ERROR_UNABLE_TO_OPEN_FILE;
}
int w = 0;
if ( write(file, data,&w) != 0 ) {
*written = -1;
delete file;
return ERROR_UNABLE_TO_WRITE_DATA;
}
*written = w;
delete file;
return 0;
}
Noter :
— les multiples passages par référence parce que la valeur de retour est
déjà occupée par le code d'erreur
— la complexité absurde de la gestion de « written », obligeant à
déclarer une variable locale afin de ne pas affecter une valeur débile
en cas d'erreur
— l'ultra-complexité du nettoyage du « file » temporaire
– la longueur du code
– la duplication du « *written = -1; » ou encore du « delete file; »
Je n'ose trop ajouter le moindre bout de code là-dedans de peur
d'exponentialiser la complexité de la gestion des variables temporaires
(de plus en plus seront à nettoyer au fur et à mesure de la progression
dans la fonction.
À comparer à la même fonction en Java :
int writeToFile(String filename, String data) throw FileException,
IOException {
File file = new File();
try {
// Lancera une FileException en cas d'erreur
open(filename, file);
// Lancera une IOException en cas d'erreur
return write(file, data);
} finally {
file.close();
}
}
Code selon JBK :
int writeToFile(char *filename, char *data, int *written) {
File *file = new File();
if ( open(filename, file) != 0 ) {
*written = -1;
return ERROR_UNABLE_TO_OPEN_FILE;
}
int w = 0;
if ( write(file, data,&w) != 0 ) {
*written = -1;
delete file;
return ERROR_UNABLE_TO_WRITE_DATA;
}
*written = w;
delete file;
return 0;
}
Noter :
— les multiples passages par référence parce que la valeur de retour est
déjà occupée par le code d'erreur
— la complexité absurde de la gestion de « written », obligeant à
déclarer une variable locale afin de ne pas affecter une valeur débile
en cas d'erreur
— l'ultra-complexité du nettoyage du « file » temporaire
– la longueur du code
– la duplication du « *written = -1; » ou encore du « delete file; »
Je n'ose trop ajouter le moindre bout de code là-dedans de peur
d'exponentialiser la complexité de la gestion des variables temporaires
(de plus en plus seront à nettoyer au fur et à mesure de la progression
dans la fonction.
À comparer à la même fonction en Java :
int writeToFile(String filename, String data) throw FileException,
IOException {
File file = new File();
try {
// Lancera une FileException en cas d'erreur
open(filename, file);
// Lancera une IOException en cas d'erreur
return write(file, data);
} finally {
file.close();
}
}
Code selon JBK :
int writeToFile(char *filename, char *data, int *written) {
File *file = new File();
if ( open(filename, file) != 0 ) {
*written = -1;
return ERROR_UNABLE_TO_OPEN_FILE;
}
int w = 0;
if ( write(file, data,&w) != 0 ) {
*written = -1;
delete file;
return ERROR_UNABLE_TO_WRITE_DATA;
}
*written = w;
delete file;
return 0;
}
Noter :
— les multiples passages par référence parce que la valeur de retour est
déjà occupée par le code d'erreur
— la complexité absurde de la gestion de « written », obligeant à
déclarer une variable locale afin de ne pas affecter une valeur débile
en cas d'erreur
— l'ultra-complexité du nettoyage du « file » temporaire
– la longueur du code
– la duplication du « *written = -1; » ou encore du « delete file; »
Je n'ose trop ajouter le moindre bout de code là-dedans de peur
d'exponentialiser la complexité de la gestion des variables temporaires
(de plus en plus seront à nettoyer au fur et à mesure de la progression
dans la fonction.
À comparer à la même fonction en Java :
int writeToFile(String filename, String data) throw FileException,
IOException {
File file = new File();
try {
// Lancera une FileException en cas d'erreur
open(filename, file);
// Lancera une IOException en cas d'erreur
return write(file, data);
} finally {
file.close();
}
}
Le 20/06/2011 23:03, JKB a écrit :Tu as une drôle de conception de la revue de code. Passons.
La revue de code en C⁺⁺ se termine généralement par « eh les mecs,
comment ça se fait que ces codes de retour ne sont pas testés ? »
Pour ensuite finir par un « Oui mais on avait déjà 42 niveaux de if
imbriqués et faudrait encore en ajouter 13 pour être complet… »
Et la décision finale est « Bon, on ne peut rien faire, ça demande de
casser les ¾ du code… »
Le 20/06/2011 23:03, JKB a écrit :
Tu as une drôle de conception de la revue de code. Passons.
La revue de code en C⁺⁺ se termine généralement par « eh les mecs,
comment ça se fait que ces codes de retour ne sont pas testés ? »
Pour ensuite finir par un « Oui mais on avait déjà 42 niveaux de if
imbriqués et faudrait encore en ajouter 13 pour être complet… »
Et la décision finale est « Bon, on ne peut rien faire, ça demande de
casser les ¾ du code… »
Le 20/06/2011 23:03, JKB a écrit :Tu as une drôle de conception de la revue de code. Passons.
La revue de code en C⁺⁺ se termine généralement par « eh les mecs,
comment ça se fait que ces codes de retour ne sont pas testés ? »
Pour ensuite finir par un « Oui mais on avait déjà 42 niveaux de if
imbriqués et faudrait encore en ajouter 13 pour être complet… »
Et la décision finale est « Bon, on ne peut rien faire, ça demande de
casser les ¾ du code… »