Folly : la bibliothèque C++ open-source de Facebook
Une initiative pour partager les outils utilisés en interne

Le , par Klaim, Membre expert
Folly : la bibliothèque C++ open-source de Facebook
Une initiative pour partager les outils utilisés en interne

Herb Sutter, l'expert reconnu du langage C++, encense dans son dernier billet de blog l'initiative de Facebook qui vient tout juste de publier en open-source sa bibliothèque d'utilités : Folly.

Cette bibliothèque contient tout un tas d'algorithmes et de structures utilisés dans le code de Facebook. L'essentiel des fonctionnalités couvre les problèmes de performances ou d'absence d'implémentations trouvés dans les bibliothèques déjà existantes comme Boost ou la bibliothèque standard.

De plus en plus d'entreprises mettent leur code source à disposition de tous et permettent de compléter les fonctionnalités fournies par les bibliothèques C++ disponibles. Certaines ont pour but d'être intégrées dans la bibliothèque standard C++, dans le but de corriger ce qui semble être pour Herb Sutter le problème majeur du C++ : le manque d'outils disponibles de façon standard.

Dépôt GitHub de Folly : https://github.com/facebook/folly.

Et vous :
Que pensez-vous de cette initiative de Facebook ?
Pensez-vous pouvoir utiliser cette bibliothèque dans vos propres projets ?

Sources :


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de Ekleog Ekleog - Membre éclairé http://www.developpez.com
le 06/06/2012 à 11:39
Sauf que, comme le fait remarquer un des articles qui est en traduction (je crois), les exceptions sont souvent moins gourmandes en ressources que l'utilisation d'un code de retour. En tout cas, tant qu'elles restent exceptionnelles, bien sûr. Mais, si il y a autant d'erreurs que de retours normaux, est-ce toujours une erreur ?
Avatar de Freem Freem - Membre émérite http://www.developpez.com
le 06/06/2012 à 12:48
La consommation en ressources du traitement des exceptions varie selon le compilateur, donc il est difficile d'affirmer de façon catégorique que ça pèse vraiment lourd.
Et, naturellement, j'ai ici parlé de ressources de façon générale.
Selon mes lectures en survol à ce sujet, il y a grosso modo deux stratégies pour les gérer:
_ augmenter la taille du code
_ augmenter les traitements processeur

Avec GCC, selon la doc, une exception n'a un coût que si elle est lancée, mais le binaire augmente un peu.
Honnêtement... J'aime beaucoup l'optimisation, mais je préfère un programme qui ne crash pas, et qui ne contiens pas de memory leak.
Donc, j'aime bien les contrôles d'erreur.
Si on veut me dire que les exceptions consomment, je veux voir un comparatif, entre un source C et un C++, ou chaque fonction du C retourne un code erreur, et ou celui-ci est systématiquement vérifié.
Ca inclut printf/scanf, naturellement...

Si il s'avère que le binaire C résultant d'un tel code est plus rapide, plus petit en RAM, plus petit sur le disque, et plus lisible, alors je serai conquis. (En fait, même juste la moitié de ces arguments commencerait à me faire réfléchir... mais bon, je doute qu'un code sans exception vérifie toutes les conditions d'erreurs. Déjà qu'avec les exceptions ce n'est pas toujours le cas...)

Sauf que:
_ coller des if partout dans le code augmente la taille du binaire, même si ce ne sont que 3 octets par occurrence pour un short jump (selon mes souvenirs d'asm)
_ coller des if partout dans le code implique des vérifications. Et chaque vérification consomme du temps processeur. J'imagine une fonction récursive qui à été appelée 50 fois... et j'ai un sérieux doute quand à la légèreté des vérifs de retour d'erreur classique.
_ "accessoirement" mélanger le code de traitement d'erreur avec le code d'exécution normal, ça rend le code illisible.

Bon, après, c'est vrai aussi, il semble qu'il est possible de bricoler un système pas trop mal en C avec signal.h et les longjump, mais je n'en ai pas encore vu, moi.
Je pense que les exceptions, c'est un peu comme l'orienté objet: quelque chose dont tout le monde parle mais qui est moins répandu qu'on ne voudrait le croire.
En tout cas, je n'en ai pas vu à mon taf actuel, ni sur les 2-3 projets open source que j'ai osé vouloir lire. (Ni l'un ni l'autre d'ailleurs: ni exceptions, ni conception orientée objet, alors que les langages le permettent...)
Avatar de Ekleog Ekleog - Membre éclairé http://www.developpez.com
le 06/06/2012 à 13:30
Citation Envoyé par Freem  Voir le message
La consommation en ressources du traitement des exceptions varie selon le compilateur, donc il est difficile d'affirmer de façon catégorique que ça pèse vraiment lourd.
Et, naturellement, j'ai ici parlé de ressources de façon générale.
Selon mes lectures en survol à ce sujet, il y a grosso modo deux stratégies pour les gérer:
_ augmenter la taille du code
_ augmenter les traitements processeur

Augmenter la taille du code => Oui mais non.
Soit il y a setjmp / longjmp ; qui génèrent des points de saut pour gérer les exceptions. Méthode qui n'est quasiment plus utilisée, car elle n'est efficace que dans le cas d'une exception très fréquente. Mais, il me semble qu'il y a des options pour la réactiver sur certains compilateurs.
Soit il y a la exception handling table (pas sûr du nom). En gros, lorsqu'on lance une exception, on va voir la table et on en tire les choses à faire. Ca alourdit un peu l'exécutable, mais ... Par rapport à tous les opcodes de jz +X ret (voire plus d'opcodes encode), je ne suis pas certain que ça augmente la taille du code par rapport à un code de gestion d'erreurs manuelle.

Citation Envoyé par Freem
Avec GCC, selon la doc, une exception n'a un coût que si elle est lancée, mais le binaire augmente un peu.
Honnêtement... J'aime beaucoup l'optimisation, mais je préfère un programme qui ne crash pas, et qui ne contiens pas de memory leak.
Donc, j'aime bien les contrôles d'erreur.

=> ?
Là, je ne comprense pas.
C'est de l'humour, peut-être ?
Parce que, au moins, avec une exception on crash proprement (destructeurs, etc.).
Avec un code de contrôle d'erreur de retour dans lequel on oublie ne serait-ce qu'une erreur possible (après tout, il suffit d'oublier un if, c'est tellement fréquent), on va d'abord tout exploser en continuant l'exécution d'un code dont les préconditions ne sont pas respectées, et ensuite on va crasher. Avec donc un risque de corruption du reste du système (fs, sauvegarde,...) beaucoup plus grand.

Citation Envoyé par Freem
Si on veut me dire que les exceptions consomment, je veux voir un comparatif, entre un source C et un C++, ou chaque fonction du C retourne un code erreur, et ou celui-ci est systématiquement vérifié.
Ca inclut printf/scanf, naturellement...

Si il s'avère que le binaire C résultant d'un tel code est plus rapide, plus petit en RAM, plus petit sur le disque, et plus lisible, alors je serai conquis. (En fait, même juste la moitié de ces arguments commencerait à me faire réfléchir... mais bon, je doute qu'un code sans exception vérifie toutes les conditions d'erreurs. Déjà qu'avec les exceptions ce n'est pas toujours le cas...)

Comment oublier de gérer une exception ?
Dans tous les cas, le binaire sera plus lent (plus de sauts conditionnels), à peu près aussi grand en RAM (opcodes supplémentaires vs. table d'exceptions), aussi grand sur le disque (idem), et moins lisible (nécessité de vérifier le code de retour même avec du SBRM) ...

Citation Envoyé par Freem
Sauf que:
_ coller des if partout dans le code augmente la taille du binaire, même si ce ne sont que 3 octets par occurrence pour un short jump (selon mes souvenirs d'asm)
_ coller des if partout dans le code implique des vérifications. Et chaque vérification consomme du temps processeur. J'imagine une fonction récursive qui à été appelée 50 fois... et j'ai un sérieux doute quand à la légèreté des vérifs de retour d'erreur classique.
_ "accessoirement" mélanger le code de traitement d'erreur avec le code d'exécution normal, ça rend le code illisible.

Bon, après, c'est vrai aussi, il semble qu'il est possible de bricoler un système pas trop mal en C avec signal.h et les longjump, mais je n'en ai pas encore vu, moi.
Je pense que les exceptions, c'est un peu comme l'orienté objet: quelque chose dont tout le monde parle mais qui est moins répandu qu'on ne voudrait le croire.
En tout cas, je n'en ai pas vu à mon taf actuel, ni sur les 2-3 projets open source que j'ai osé vouloir lire. (Ni l'un ni l'autre d'ailleurs: ni exceptions, ni conception orientée objet, alors que les langages le permettent...)

En bref, un énorme +1.
Avatar de Klaim Klaim - Membre expert http://www.developpez.com
le 06/06/2012 à 14:49
Ce que beaucoup oublient avec l'argument des ifs a la place des exceptions, c'est que le choix de ne pas utiliser d'exceptions n'implique pas que l'on va checker les erreurs. C'est ce qui se passe dans beaucoup de jeux vidéos: on met beaucoup beaucoup d'assertions pour crasher le plus vite possible pendant le développement ou au moins logger et puis continuer, mais une fois que le jeu est suffisamment prêt on vire tout et il n'y a aucune vérification d'erreur. Une des raisons qui rends cela possible est tout simplement qu'un jeu console n'a que des inputs fixes et prévisibles, du coup il est possible de se retrouver, après beaucoup de travail, avec un jeu qui
tourne "parfaitement" sans aucune vérification du tout.

Cela étant dis, hors du contexte d'un jeu console, pour une console des anciennes générations du moins, cet argument ne tiens plus.

Pour le point sur l'activation des exceptions: en théorie on est censé ne pas payer si il n'y a aucun throw de fait. Dans la pratique on paye mémé dans ce cas. Par contre, aujourd’hui sur la plupart des plateformes (mais pas sur console ou sur la plupart des systèmes embarques, pas les smartphones) le cout est très faible donc ça va encore. Sur certaines consoles comme la DS le simple fait qu'il n'y ai que 4mo de mémoire virtuelle "normale" a laquelle on doit imputer la taille de l’exécutable fais que le coût du mécanisme d'exception en terme de taille d’exécutable n'est pas du tout acceptable. Je ne sais pas pour la 3ds qui a sacrement beaucoup plus de mémoire, mais j’imagine qu'il y a des contraintes similaires parce que c'est pas non plus un pc ou même un smartphone.
Avatar de Luc Hermitte Luc Hermitte - Expert éminent http://www.developpez.com
le 06/06/2012 à 16:50
Ouais enfin. Il y a erreur alors.
Si le code peut utiliser des assert plutôt que des if dans tous les sens, cela signifie que les éventuelles erreurs trouvées sont des erreurs de programmation et non de problèmes dans le contexte de l'exécution (comme une connexion réseau à internet perdue).

Les exceptions n'ont pas leur place. Pas plus que les if. C'est des assertions qu'il faut, et le débat exception ou pas n'a pas lieu d'être pour ces "erreurs là".
Avatar de Klaim Klaim - Membre expert http://www.developpez.com
le 06/06/2012 à 18:31
Oui mais la encore il y a subtilité.

Quel est l'effet d'une assertion? Log + crash souvent.

Mais pour un jeu ça peut etre problématique. Une série d'assertions peuvent donner plus d'indices sur l'ampleur d'un probleme qu'une seule assertion qui fait tout crasher.

Du coup beaucoup d'assertions sont implémentées pour logger et etre evaluable optionellement, pour quand meme generer du code dans le cas ou l'assertion ne passe pas OU pour crasher OU pour lancer une exception.
En plus les assertions sont rarement gardées dans le code d'un jeu, ils sont utilisés seulement dans des versions "debug" ou "release debug" du jeu, pour des soucis de performances.

Du coup exceptions, tests unitaires et assertions devraient marcher mains dans la mains, mais devraient être desactivable si besoin.

Enfin bref, ce que je veux dire c'est que comprendre l'ampleur et du sujet mais aussi comprendre que les termes employés ont tendance à englober trop de choses qui ne sont pas forcément sous entendues par toutes les parties de la discussion, fait que les discussions tournent rapidement steriles sur le sujet...
Avatar de Ekleog Ekleog - Membre éclairé http://www.developpez.com
le 06/06/2012 à 19:53
Citation Envoyé par Klaim  Voir le message
Ce que beaucoup oublient avec l'argument des ifs a la place des exceptions, c'est que le choix de ne pas utiliser d'exceptions n'implique pas que l'on va checker les erreurs. C'est ce qui se passe dans beaucoup de jeux vidéos: on met beaucoup beaucoup d'assertions pour crasher le plus vite possible pendant le développement ou au moins logger et puis continuer, mais une fois que le jeu est suffisamment prêt on vire tout et il n'y a aucune vérification d'erreur. Une des raisons qui rends cela possible est tout simplement qu'un jeu console n'a que des inputs fixes et prévisibles, du coup il est possible de se retrouver, après beaucoup de travail, avec un jeu qui
tourne "parfaitement" sans aucune vérification du tout.

Auquel cas, un équivalent exceptions qui permet de conserver la remontée de pile automatique (bien sûr, si on ne cherche de travail que pour les assertions ça ne servira à rien, mais bon...) :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define THROW(...) throw __VA_ARGS__ 
#define TRY(...) try { __VA_ARGS__ } 
#define CATCH_EXPAND(...) __VA_ARGS__ 
#define CATCH(T, ...) catch(CATCH_EXPAND T) { __VA_ARGS__ } 
// Bien sûr, en release, on supprime tous les rhs 
 
// Usage : 
TRY ( 
  // Code normal, comme si try { } 
  THROW(some::exception<a, b, c>(abc)); 
  // etc. 
) CATCH ((some::exception<a, b, c> const & e), 
  // Code de gestion d'erreur) 
)
Après, j'avoue en voir mal l'intérêt.

Cela étant dis, hors du contexte d'un jeu console, pour une console des anciennes générations du moins, cet argument ne tiens plus.

Pour le point sur l'activation des exceptions: en théorie on est censé ne pas payer si il n'y a aucun throw de fait. Dans la pratique on paye mémé dans ce cas. Par contre, aujourd’hui sur la plupart des plateformes (mais pas sur console ou sur la plupart des systèmes embarques, pas les smartphones) le cout est très faible donc ça va encore. Sur certaines consoles comme la DS le simple fait qu'il n'y ai que 4mo de mémoire virtuelle "normale" a laquelle on doit imputer la taille de l’exécutable fais que le coût du mécanisme d'exception en terme de taille d’exécutable n'est pas du tout acceptable. Je ne sais pas pour la 3ds qui a sacrement beaucoup plus de mémoire, mais j’imagine qu'il y a des contraintes similaires parce que c'est pas non plus un pc ou même un smartphone.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream> 
 
#define C 0x42424242 
 
int f(int i) { 
   if (i == C + 1) { 
#ifdef WITH_EXC 
      throw "some exception"; 
#else 
      return 0x42; 
#endif 
   } 
   return i - C; 
} 
 
int main() { 
   int i; 
   std::cin >> i; 
   i += C; 
#ifdef WITH_EXC 
   try { 
      return f(i); 
   } catch(...) { 
      return 1; 
   } 
#else 
   return f(i); 
#endif 
}
Compilé avec WITH_EXC, g++ triche : il inline. Mais on peut décemment supposer que les fonctions méritant des exceptions ne seront, théoriquement, pas inlinées.

Sans WITH_EXC :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(gdb) disas main 
Dump of assembler code for function main: 
   0x0000000000400810 <+0>:     sub    rsp,0x18 
   0x0000000000400814 <+4>:     mov    edi,0x600e60 
   0x0000000000400819 <+9>:     lea    rsi,[rsp+0xc] 
   0x000000000040081e <+14>:    call   0x4007c0 <_ZNSirsERi@plt> 
   0x0000000000400823 <+19>:    mov    edi,DWORD PTR [rsp+0xc] 
   0x0000000000400827 <+23>:    add    edi,0x42424242 
   0x000000000040082d <+29>:    mov    DWORD PTR [rsp+0xc],edi 
   0x0000000000400831 <+33>:    call   0x400980 <_Z1fi> 
   0x0000000000400836 <+38>:    add    rsp,0x18 
   0x000000000040083a <+42>:    ret     
   0x000000000040083b <+43>:    mov    rdi,rax 
   0x000000000040083e <+46>:    call   0x4007f0 <__cxa_begin_catch@plt> 
   0x0000000000400843 <+51>:    call   0x4007e0 <__cxa_end_catch@plt> 
   0x0000000000400848 <+56>:    mov    eax,0x1 
   0x000000000040084d <+61>:    jmp    0x400836 <main+38> 
End of assembler dump. 
(gdb) disas f 
Dump of assembler code for function _Z1fi: 
   0x0000000000400980 <+0>:     cmp    edi,0x42424243 
   0x0000000000400986 <+6>:     je     0x40098f <_Z1fi+15> 
   0x0000000000400988 <+8>:     lea    eax,[rdi-0x42424242] 
   0x000000000040098e <+14>:    ret     
   0x000000000040098f <+15>:    push   rax 
   0x0000000000400990 <+16>:    mov    edi,0x8 
   0x0000000000400995 <+21>:    call   0x4007b0 <__cxa_allocate_exception@plt> 
   0x000000000040099a <+26>:    xor    edx,edx 
   0x000000000040099c <+28>:    mov    QWORD PTR [rax],0x400a54 
   0x00000000004009a3 <+35>:    mov    esi,0x600f80 
   0x00000000004009a8 <+40>:    mov    rdi,rax 
   0x00000000004009ab <+43>:    call   0x4007d0 <__cxa_throw@plt> 
End of assembler dump.
En suivant le déroulement de main, je ne vois nulle part ne fût-ce que la plus infime trace de code dédié à l'exception sur le chemin du code normal (réserver pile, lire entier, ajouter constante, appeler f, retourner).
En suivant celui de f, je ne vois que le strict nécessaire : un unique saut conditionel, contrairement à un test de retour où il faudrait tester à chaque appel de fonction.

Où est donc le coût des exceptions ? (A part dans le poids mémoire du runtime __cxa_*, qui sera probablement de toute façon inclus, sauf peut-être si -fno-exceptions est passé.)
Avatar de Klaim Klaim - Membre expert http://www.developpez.com
le 07/06/2012 à 3:42
Citation Envoyé par Ekleog
Auquel cas, un équivalent exceptions qui permet de conserver la remontée de pile automatique (bien sûr, si on ne cherche de travail que pour les assertions ça ne servira à rien, mais bon...) :

Ca depends. Une simple macro d'assertion (quelle que soit son comportement) "poluera" moins le code que ce que tu proposes, sauf dans les parties qui sont censes logger les erreurs. Comme souvent ce log se passe dans une macro d'assertion, ce que tu proposes deviens moins efficace.

Dans tous les cas, personnellement je preferes avoir des macro d'assertion testables, qui potentiellement peuvent lancer des exception..ou pas, mais qui log puis debugbreak avant de faire quoi que ce soit d'autre.

(je sens qu'on a completement change de sujet au passage).

Où est donc le coût des exceptions ? (A part dans le poids mémoire du runtime __cxa_*, qui sera probablement de toute façon inclus, sauf peut-être si -fno-exceptions est passé.)

Je vais omettre la memoire un instant et suggerer que tu testes sur le code d'un projet de la complexite d'un jeu. Je veux dire, un jeu ou les perfs sont importantes. Genre.. par exemple prends Ogre, compile avec et sans et lance les tests.
L'exemple que tu donnes n'a aucun interet parcequil est evident meme pour le le compilateur, tandis que si tu commences a complexifier c'est un autre sujet.

Cela dit je n'ai pas le temps de faire le test moi meme, pardon.

En revanche il est important de signaler que beaucoup d'ameliorations (en particulier dans gcc) ont ete faites pour effacer ce probleme, aucours des dernieres annees.

Je n'ai pas compare aujourdhui mais ca serait interessant de faire un test complet, avec msvc, clang et gcc, voir l'impact aujourdh'ui, sur un projet de jeu.

J'aurais bien propose un de mes projets comme sujet, peut 'etre ce prototype? http://radiantlasercross.com mais je n'ai jamais pris le temps de le compiler pour autre chose que msvc.
Avatar de Freem Freem - Membre émérite http://www.developpez.com
le 07/06/2012 à 11:30
Citation Envoyé par Ekleog  Voir le message
=> ?
Là, je ne comprense pas.
C'est de l'humour, peut-être ?

Non, je me suis juste mal exprimé... je pensais aux contrôle d'erreur au sens large du terme, c'est à dire que je pense que mettre un saut classique vaut toujours mieux que rien, même si je préfère les exceptions au sauts classiques.

Citation Envoyé par Klaim  Voir le message
Cela étant dis, hors du contexte d'un jeu console, pour une console des anciennes générations du moins, cet argument ne tiens plus.

Reste à définir le terme ancienne génération, alors, je suppose.
Effectivement, dans le cas d'un environnement maîtrisé à 100%, les exceptions n'ont pas lieu d'être. Mais maîtrisé à 100% implique 0 connectivité au monde extérieur.
Je n'ai jamais été un "consoleux" mais il me semble que la DS permet le multi-joueur en connectant plusieurs consoles, non?
De ce fait, il y a un réseau qui se crée...
Sinon, il y a aussi l'option ou le dev ne fait pas d'allocation dynamique, et que du coup, il n'y a pas de risque de buffer overflow. Sinon, risque d'explosion, encore une fois.
Cela dis, pour tempérer mes propos, j'ajouterai qu'en plus de ne jamais jouer sur console que chez quelques potes, je n'ai jamais non plus développé de jeux pour console (et de façon générale, un part un casse-brique en basic sur ma TI82 au lycées, pas vraiment fait de jeux... et clairement l'environnement était contrôlé à 95% sur TI - restait le dépassement de capacité a éviter lors des copies de matrices qui représentaient les niveaux/sauvegardes mais je n'avais de toute façon aucune façon de les gérer - )

Pour le point sur l'activation des exceptions: en théorie on est censé ne pas payer si il n'y a aucun throw de fait. Dans la pratique on paye mémé dans ce cas.

Ma mémé a plus de sous que moi, c'est p'tet pour ça
Blague à part (c'était juste pour me dérider en ce jeudi au temps pourri) il y a ce thread sur SO:
http://stackoverflow.com/questions/6...n-handling-add

Et les 2 premiers posts, avec leurs scores semblent montrer que globalement, le surcoût des exception est négligeable, tant au niveau de la taille du binaire que de l'exécution.

Citation Envoyé par Klaim  Voir le message
Oui mais la encore il y a subtilité.
Quel est l'effet d'une assertion? Log + crash souvent.

C'est aussi ainsi que les profs que j'ai eus me décrivaient le rôle d'une exception. Le but du jeu n'était pas que le programme survive, selon leurs explications, juste que le dev ait un rapport de bug plus complet limite... En même temps, on ne les as que survolées (et il n'a jamais été précisé que printf/scranf ont des valeurs de retours)...
La ou j'ai commencé à comprendre leur rôle, c'est le jour ou je suis tombé sur un document traitant de l' "exception safety" de Boost.

Citation Envoyé par Klaim  Voir le message
Enfin bref, ce que je veux dire c'est que comprendre l'ampleur et du sujet mais aussi comprendre que les termes employés ont tendance à englober trop de choses qui ne sont pas forcément sous entendues par toutes les parties de la discussion, fait que les discussions tournent rapidement steriles sur le sujet...

C'est sûr.
Personnellement, quand je pense aux assertions, je pense à "assert()".
Du coup, c'est automatiquement supprimé quand je passe en mode release.
Depuis C++11, je devrais aussi penser à "static_assert()" (ou un truc du genre) qui permet juste une vérification par le compilo, et n'a donc aucune influence dans le binaire.
Donc, du code censé contrôler les problème de code, les bugs introduits par le dev.

Ah, c'est vrai, on pourrait aussi penser aux exceptions "std::logic_error" mais je ne sais pas quels sont leurs rôles et cas d'utilisations, donc j'ai tendance à ne pas y penser.
Surtout qu'en général, en cas d'erreur de logique, ça me mène au crash peu après
Donc je vois plus les exceptions, et contrôles d'erreurs en if, comme un moyen de prévenir et traiter les évènements sur lesquels on a aucune prise lors de la programmation:
_ mémoire insuffisante pour traiter une opération
_ rupture de réseau
_ fichier d'entrée corrompu
_ saisie utilisateur foireuse (genre il entre un texte dans un champ où on lui demande de mettre un nombre, et la conversion foire en lançant une exception)

Citation Envoyé par Klaim  Voir le message
(je sens qu'on a completement change de sujet au passage).

En effet

PS: ta démo pourrait devenir un jeu d'arcade relativement fun
Avatar de Luc Hermitte Luc Hermitte - Expert éminent http://www.developpez.com
le 07/06/2012 à 19:43
Citation Envoyé par Klaim  Voir le message
Oui mais la encore il y a subtilité.

Quel est l'effet d'une assertion? Log + crash souvent.

Mais pour un jeu ça peut etre problématique. Une série d'assertions peuvent donner plus d'indices sur l'ampleur d'un probleme qu'une seule assertion qui fait tout crasher.

Du coup beaucoup d'assertions sont implémentées pour logger et etre evaluable optionellement, pour quand meme generer du code dans le cas ou l'assertion ne passe pas OU pour crasher OU pour lancer une exception.
En plus les assertions sont rarement gardées dans le code d'un jeu, ils sont utilisés seulement dans des versions "debug" ou "release debug" du jeu, pour des soucis de performances.

[...]

Enfin bref, ce que je veux dire c'est que comprendre l'ampleur et du sujet mais aussi comprendre que les termes employés ont tendance à englober trop de choses qui ne sont pas forcément sous entendues par toutes les parties de la discussion, fait que les discussions tournent rapidement steriles sur le sujet...

Il y a un truc qui me perturbe dans ta réaction à mon intervention.
Et je crois que j'ai enfin trouvé : une assertion en phase de dév va non seulement crasher, mais aussi et surtout provoquer un core dump (man ulimit pour ceux sous *nix qui n'ont pas de core générés).
Et un fichier core, c'est juste royal car la pile d'appel (sur tous les threads) est stockée au moment du crash.
Nul besoin d'avoir une série de logs quand on dispose d'un état complet du programme au moment du plantage (et donc l'état de toutes les variables qui étaient encore en train de vivre).

Il n'y a de fait pour moi aucune subtilité.
- erreur de prog -> assertions => core dump => état complet (au détail des optims faites à notre insu et de certaines résolutions de meta-prog template) au moment du plantage.
- erreur dans le contexte (très bien explicité par Freem) -> 110000 ifs, ou des exceptions. Et ça, ce n'est pas désactivable dans le produit final.
Et ici même la question initiale se pose : "if ou exception?" ; "Quel est le mécanisme qui coute le moins cher -- quand non buggué -- sur la plateforme ciblée ?"
(et effectivement, deux des articles traduits (/en cours de) couvrent ce sujet)

Maintenant si les consoles ne peuvent pas générer de fichiers core (ou équivalent), je comprends que la situation soit pourrie et que vous deviez pervertir le fonctionnement des assertions pour tracer des choses comme la pile d'appel. Car je suis d'accord, un crash sans fichier core, cela n'apporte rien.

(oui on peut forker la discussion)

Reste le sujet connexe de la programmation défensive qui n'a pas encore été proprement abordé.
Avatar de Klaim Klaim - Membre expert http://www.developpez.com
le 08/06/2012 à 3:57
Ce que j'essayais vainement d'expliquer c'est que a part tester une verite, l'implmentation d'une assertion est vraiment totalement dependante de ce qu'on veut qu'elle fasse. Par exemple j'ai vu des assertions qui font ce que tu decris, mais aussi des assertions qui ne font que logger (quelle que soient les infos et leur forme, ca peut ne pas etre du texte) et continuer ensuite, ou bien crasher, ou bien juste declencher un debugbreak, etc.

Selon les types de jeux avoir des assertions qui stoppent le programme peut 'etre problematique meme si c'est bon pour que les programmeurs continuent a bosser.

Du coup toutes les assertions ne sont pas equivalentes, et beaucoup de gens basent leur definition sur ce qu'ils ont vu et manipule alors que dans la pratique la variete de comportement des assertions est suffisamment importante pour facilement embrouiller une discussion comme celle ci.
Offres d'emploi IT
Ingénieur système middleware (H/F)
Atos - Rhône Alpes - Lyon (69000)
Développeur Java - Alternance (H/F)
FIGARO CLASSIFIEDS - Aquitaine - Bruges (33520)
Développeur php5/symfony2
AMETIX - Ile de France - Paris (75000)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique Accueil