IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Perte de sens du C++11


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut Perte de sens du C++11
    Salut à tous

    Bon, pas d’inquiétude avec mon titre trollesque, j'attaque pas le C++11.

    Je discutais avec germinolegrand sur le chat suite à ce bout de code qu'il me présente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::list<std::pair<sf::Vector2f, sf::ConvexShape>> m_triangles;
    auto it = std::find_if(begin(m_triangles), end(m_triangles), [pos](const std::pair<sf::Vector2f, sf::ConvexShape> &p){return p.first == pos;});
    Jusque là, rien à dire, utilisation classique des lambdas...

    En bien si, je critique (comme d'habitude )

    On comprend que l'on a une liste de triangles avec le nom de la variable, mais les triangles, ce sont std::pair<sf::Vector2f, sf::ConvexShape> ou sf::ConvexShape ? A quoi correspond sf::Vector2f ? Ok, on fait un find pour trouver le triangle qui à un sf::Vector2f donné, mais ça correspond à quoi ? Trouver les triangles qui ont un point commun ? Le même centre ?

    Avec les facilités d'écriture du C++11, ne risque-t-on pas de voir une utilisation à outrance, quitte à perdre de la sémantique ?

    Sur l'exemple de code précédent, j'aurais plus vu l'utilisation d'une classe (je simplifie le code un peu, en particulier au niveau des accès) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct Triangle {
        sf::Vector2f center;
        sf::ConvexShape points;
        bool operator== (Triangle const& t) const { return t.center == center; }
    };
     
    auto it = std::find(begin(m_triangles), end(m_triangles), pos);
    Dans l'idée qu'une classe est un contrat entre le dev d'une classe et les utilisateurs de cette classe, créer un tel objet permet de :
    1. définir correctement un sémantique sur Triangle (de valeur ici), c'est à dire comment doit être compris cette classe, ce quelle représente et donc que l'on peut faire (ou pas) avec cette classe
    2. de contrôler les accès aux variables membres (rien n'interdit dans le code avec pair de modifier le centre d'un triangle, ce qui n'aurait pas de sens)
    3. que le lecteur sache à quoi correspond les variables qu'il manipule. sf::Vector2f peut être un angle, le barycentre, le centre des cercles conscrit ou circonscrits, etc.

    Idem pour le find. On peut le laisser tel quel dans le code. Ou on peut aussi l'encapsuler dans une fonction pour lui donner un sens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class TRIANGLE>
    auto findCorrespondingTriangle(typename TRIANGLE::CenterType const& pos, list<TRIANGLE> const& triangles) {
        return std::find(begin(triangles), end(triangles), pos);
    }
    (bon, c'est l'idée. Pour mieux faire, on peut également ajouter une abstraction pour le type de conteneur et proposer une politique pour le type de correspondance que l'on recherche : triangles avec centre en commun, triangles sécants, etc)


    Bon, sur 2 lignes de code, c'est un peu caricatural. Mais j'ai l'impression que l'on voit de plus en plus ce genre de code, où l'auteur pense (à tort à mon avis, si c'est pour économiser 2 lignes) que plus c'est court, mieux c'est.
    Vous en pensez quoi ?

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Salut,

    J'ai l'impression que tu te complique la vie pour rien. Le langage permet l'obfuscation, mais il est bien assez riche pour l'éviter, il ne tient qu'aux développeurs d'y prendre garde.

    Vouloir faire une classe pour ces deux champs me semble être une erreur, et de manière général vouloir faire de l'objet sur une séquence de tuple (ie une BDD) me semble être une abstraction non nécessaire et qui peut apporter des problèmes (il me semble que Emmanuel Deloget a faire un article là dessus d'ailleurs).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    typedef sf::Vector2f CenterType;
    typedef sf::ConvexShape TriangleType;
    typedef std::tuple<CenterType,TriangleType> EntityType;
    typedef std::list<EntityType> DataBaseType;
     
    enum CaseName {CenterCase,TriangleCase};
     
    DataBaseType data_base;
    auto it = std::find_if(
      begin(data_base),
      end(data_base),
      [&center](const EntityType& entity){
        return  get<CenterCase>(entity) == center;
      }
    );
    NB: Je ne connais pas le vocabulaire des bases de données, il y a peut-être plus adapté.

    Personnellement, écrit comme ça, je trouve ça lisible (mis à par les typedef à adpater pour le vocabulaire).

    PS: Code non testé, c'est juste pour l'idée.

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Une partie du problème prédate largement le C++11 : Il s'agit de std::pair. D'un certain point de vue, ce n'est rien d'autre qu'une classe à deux membres pour laquelle on a été trop fainéant pour trouver un nom (bon, ok, avec tuple, C++11 pousse ça dans une nouvelle dimension).

    Et pour moi, utiliser std::pair pour remplacer une vraie classe, avec ses invariants, son utilisation dans plusieurs contextes... a toujours été une hérésie (j'aurais d'ailleurs bien aimé une map dont je puisse décider du value_type et du membre qui constitue la clef).

    Maintenant, il faut avouer que quand la pair n'est utilisée qu'à un seul endroit, ou quand on fait une bibliothèque assez bas niveau pour laquelle on ne sait pas associer de sens métier à first et second, et bien std::pair est assez adapté.

    Je pense que c'est pareil pour le find. D'ailleurs, pour moi, ici, le problème n'est pas que le lambda et le fait qu'il n'est pas nommé, mais juste que l'on a un find spécialisé non nommé, le problème serait identique si on avait non pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    auto it = std::find_if(begin(m_triangles), end(m_triangles), [pos](const std::pair<sf::Vector2f, sf::ConvexShape> &p){return p.first == pos;}
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    auto it = std::find_if(begin(m_triangles), end(m_triangles), IsAtSamePos(pos));
    Qui reste bien moins clair que ton findCorrespondingTriangle (même si je n'aime pas la manière dont tu l'as déclaré, mais c'est un autre sujet, c'est son existence qui compte).

    Si on doit rechercher ainsi une seule fois un triangle, dans le cadre d'une algorithme plus évolué, j'aime bien la version avec lambda non encapsulée. S'il s'agit d'un service à rendre en tant que tel, de manière répétée, et bien, je ferais soit une fonction libre, soit carrément une classe gérant un ensemble de triangles, avec ses propres invariants, etc. Et dans les deux cas, j'aurais un test unitaire de cette fonction.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    J'aurais tendance à plussoter Loïc...

    Le problème ne vient pas des lambda de C++11, mais de la std::pair.

    Après tout, une std::pair n'est jamais... qu'un ensemble de données pour lesquels on a décidé qu'elle allaient bien l'une avec l'autre.

    Il se fait que la STL considère plus pratique d'utiliser cet ensemble de données lorsqu'il s'agit de gérer des tableaux associatifs clés / valeurs (les std::map, si vous n'aviez pas traduit ) en donnant un sens particulier à chaque donnée (la clé pour first, la valeur pour second), avec tout ce que cela implique.

    Il se fait que, contrairement à std::map, la std::list
    • n'offre aucune garantie d'unicité des clés
    • n'offre aucune garantie de tri par rapport aux clés
    • n'offre aucune garantie d'accès en O(log N) sur base des clés
    Il n'est donc pas étonnant que quelqu'un puisse envisager d'utiliser une std::pair pour... ce que c'est: deux valeurs de type (éventuellement) distinct qui vont particulièrement bien ensemble, pour une raison qui n'appartient qu'à celui qui décide de l'utiliser.

    A partir de là, il faut bien fournir "quelque chose" qui permette à std::find de fonctionner.

    L'utilisateur a décidé d'utiliser une expression lambda, et, pour ma part, tant que l'utilisateur n'utilise qu'une fois ce code pour rechercher un élément, il aurait sans doute tort de se priver des lambda quand on sait ce que nous couterait le fait de s'en passer.

    En effet, les solutions pour s'en passer vont de la création d'une fonction libre à la création pure et simple d'un foncteur, ce qui peut réellement sembler excessif (en C++11 du moins) si l'objectif n'est d'utiliser ce code de recherche particulier qu'une seule et unique fois.

    Par contre, on peut réellement se poser la question de savoir si l'utilisateur n'aurait pas eu plus intérêt à créer sa propre structure, avec des noms plus cohérents (par rapport à l'usage qui en est fait) pour représenter cette paire de données.

    Et, même sur ce point, on peut encore pinailler

    En effet, si la std::pair<sf::Vector2f, sf::ConvexShape> n'est utilisée qu'à usage interne, bah, ma foi... on peut juste regretter que cela nous impose une dépendance supplémentaire et que cela nous fasse perdre un peu de lisibilité (et surtout "d'auto commentarité") au niveau du code.

    Bien sur, il aurait sans doute été préférable que l'utilisateur nous crée une jolie structure avec un nom qui indique clairement à quoi elle sert, et des noms pour les deux données qu'elle représente qui, là aussi, nous donnent une indication précise de ce à quoi on a à faire, mais il ne s'agit, au pire, que d'une violation de "coding rules" propres au projet, si tant est qu'il en existe

    Ceci dit, je reconnais sans conteste qu'il y a largement moyen de mieux faire au niveau de la lisibilité du code.

    Je crois cependant que ce n'est pas du à l'expression lambda, ni même à l'utilisation du terme auto (car ce sont les deux seules possibilités offertes par C++11 qui sont en cause), mais bien que c'est du à une utilisation irraisonnée de std::pair, et ca, ca existe depuis longtemps
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    J'ai l'impression que tu te complique la vie pour rien. Le langage permet l'obfuscation, mais il est bien assez riche pour l'éviter, il ne tient qu'aux développeurs d'y prendre garde.
    J'avais prévenu, l'exemple est un peu caricatural
    Mais le but est bien cette mise en garde : c'est pas parce que l'on peut le faire qu'il faut le faire

    Et pour moi, utiliser std::pair pour remplacer une vraie classe, avec ses invariants, son utilisation dans plusieurs contextes... a toujours été une hérésie (j'aurais d'ailleurs bien aimé une map dont je puisse décider du value_type et du membre qui constitue la clef).

    Maintenant, il faut avouer que quand la pair n'est utilisée qu'à un seul endroit, ou quand on fait une bibliothèque assez bas niveau pour laquelle on ne sait pas associer de sens métier à first et second, et bien std::pair est assez adapté.
    On est d'accord. Perso, utiliser pair ou tuple en interne dans une fonction ou entre fonction membres (donc comme alternative à une nested class) me choque pas.
    Par contre, manipuler des pair et tuple entre plusieurs classes commence à me faire réfléchir (je l'interdit pas, mais je me pose la question de créer une classe). Même un pair<bool, Result> me plait pas trop (même si pour des raisons de facilité, on utilise souvent)

    Or ici, on parle de triangles. Donc probablement qu'un moment donné il faudra les créer, les lire dans un fichier, les afficher, peut être faire des manipulations géométriques dessus... Ça commence à faire beaucoup pour un simple pair
    Finalement, utiliser pair et tuple revient à concevoir les objets que comme un regroupement de données, sans signification particulière et surtout sans contraintes internes (pas d'invariant de classe à vérifier, pas de conditions sur les paramètres). Bref, on en revient au problème classique de concevoir les classes comme conglomérat de données et plus comme fournisseur de services.

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    (EDIT grillé par koala01)

    Bien sur, il aurait sans doute été préférable que l'utilisateur nous crée une jolie structure avec un nom qui indique clairement à quoi elle sert, et des noms pour les deux données qu'elle représente qui, là aussi, nous donnent une indication précise de ce à quoi on a à faire, mais il ne s'agit, au pire, que d'une violation de "coding rules" propres au projet, si tant est qu'il en existe

    Ceci dit, je reconnais sans conteste qu'il y a largement moyen de mieux faire au niveau de la lisibilité du code.
    C'est bien sur un choix de conception. Mais comme dit précédemment, pour moi, il y a suffisamment de choisir à faire sur un triangle pour justifier la création d'une classe. Et le création d'un opérateur == (sémantique de valeur)

    Je crois cependant que ce n'est pas du à l'expression lambda
    J'ai quand même l'impression que les lambdas favorise le raisonnement en termes de regroupement de données. L'utilisateur réfléchit à comment il va manipuler les données, au moment où il les manipule, et l'expression de cette réflexion est le lambda (code local au moment de l'utilisation qui manipule directement les données)
    Sans les lambdas, il me semble que l'on est plus obligé de réfléchir à partir de la classe et des services qu'elles fournit. Dans l'exemple, le code permettant de vérifier l'égalité est dans le lambda, c'est à dire dans le code utilisateur, alors que l'égalité des triangles devrait être intrinsèque au type triangle.


    Autre façon de voir les choses.
    Si on est un vieux de la veille, on va peut être partir sur la définition d'une classe complète, avec 50 fonctions membres et tous les services possibles et imaginables.
    Si on est un petit jeune qui tente d'être "agile", on va écrire que le code que l'on a besoin, au moment où l'on en a besoin. On va se faire un pair ou un tuple et se faire un lambda là où on utilise notre triangle. Ok. Puis on va manipuler notre triangle à un autre endroit. Et on va créer un second lambda (donc le code sera peut être identique au premier). Puis un troisième endroit et un troisième lambda. Et on réalise alors que finalement, c'est peut être pas la bonne approche, mais la refactorisation coûtera trop chère...

    Bref, les pair, tuple et lmabda sont des fonctionnalités qui permettent de gagner du temps et des lignes de code. Mais cela ne dispense pas de bien réfléchir à sa conception avant


    @JolyLoic moi non plus j'aime pas le définition de ma fonction

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    (EDIT grillé par koala01)


    C'est bien sur un choix de conception. Mais comme dit précédemment, pour moi, il y a suffisamment de choisir à faire sur un triangle pour justifier la création d'une classe. Et le création d'un opérateur == (sémantique de valeur)


    J'ai quand même l'impression que les lambdas favorise le raisonnement en termes de regroupement de données. L'utilisateur réfléchit à comment il va manipuler les données, au moment où il les manipule, et l'expression de cette réflexion est le lambda (code local au moment de l'utilisation qui manipule directement les données)
    Sans les lambdas, il me semble que l'on est plus obligé de réfléchir à partir de la classe et des services qu'elles fournit. Dans l'exemple, le code permettant de vérifier l'égalité est dans le lambda, c'est à dire dans le code utilisateur, alors que l'égalité des triangles devrait être intrinsèque au type triangle
    Je crois que les habitués du forum me connaissent assez que pour savoir que je suis particulièrement attaché au principes S.O.L.I.D, et je ne peux donc qu'être tout à fait d'accord avec toi quant au fait qu'une classe clairement définie, avec une responsabilité clairement définie et des services associés aurait sans conteste été un bien meilleur choix que la std::pair...

    Je ne reviens absolument pas là dessus.

    Je t'accorde d'autant plus volontiers le fait, l'expression lambda aurait sans doute eu énormément d'avantage à se trouver dans un foncteur particulier que je suis tout à fait de ton avis sur ce sujet aussi

    Cependant, ces deux avis, auxquels je tiens fondamentalement, sont essentiellement justifiés dans le cas où les données manipulées (et le foncteur qui va avec) sont accessibles "à peu près partout".

    Par contre, si tu as une classe et une séries de foncteurs qui vont avec et qui sont utilisés de manière plus ou moins récurrente et que, dans un cas bien particulier (et j'insiste sur ce terme ) , tu te trouves dans une situation où tu as besoin d'une comparaison différente pour une raison qui est propre à un comportement bien particulier, je peux concevoir que l'expression lambda permet de faire les choses beaucoup plus facilement et rapidement.

    C'est exactement le sens général de mon intervention précédente où je disais
    Citation Envoyé par moi meme
    tant que l'utilisateur n'utilise qu'une fois ce code pour rechercher un élément
    et
    Par contre, on peut réellement se poser la question de savoir si l'utilisateur n'aurait pas eu plus intérêt à créer sa propre structure, avec des noms plus cohérents (par rapport à l'usage qui en est fait) pour représenter cette paire de données.
    sous entendu soit une simple structure "classique" (oserais-je dire C style ) soit une classe avec tout ce qui permet de respecter l'OCP

    Mais, avant de taper l'utilisateur pour l'utilisation de l'expression lambda, je le taperai beaucoup plus surement pour l'utilisation "abusive" de la std::pair, dans le cas présent (et sans savoir l'utilisation qui peut etre faite de cette structure de donnée par ailleurs )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Pour répondre à l'utilisation de std::pair, je vais préciser ce qui motive son utilisation, bien qu'en y repensant std::tuple est peut-être plus adapté.

    Les deux éléments du pair ne sont qu'une seule et même donnée exprimée sous différentes formes (entendez qu'à partir de la première on peut calculer la deuxième et inversement). C'est donc une information redondante, toutefois cela évite un calcul lourd et fastidieux de conversion à chaque fois qu'on a besoin de manipuler ces données sous une forme ou sous une autre. La première forme sert à faire tous les calculs de collision, d'existence, etc. La 2e sert à l'affichage, et la recréer à chaque frame serait pure perte de performance. La 2e contient d'autres données, toutefois en l'état actuel des choses ces données ne sont pas utilisées/déterminables par calcul depuis la 1e forme.

    Pour le sf::Vector2f et la dépendance que cela crée avec SFML, je dirais que je prend le parti d'exploiter un framework au maximum.

    Pour ce qui est de s'en servir une seule fois de cette lambda, je dirais que si j'avais à la réutiliser je me contenterais de rajouter une fonction decltype(m_triangles)::iterator findTriangle(const sf::Vector &center) qui contiendrait simplement cette ligne.

  9. #9
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Finalement, utiliser pair et tuple revient à concevoir les objets que comme un regroupement de données, sans signification particulière et surtout sans contraintes internes (pas d'invariant de classe à vérifier, pas de conditions sur les paramètres). Bref, on en revient au problème classique de concevoir les classes comme conglomérat de données et plus comme fournisseur de services.
    Totalement d'accord, et je suis d'accord avec Philippe et Loic, si l'on peut faire une classe avec une sémantique bien déterminé, alors il faut le faire, avec les services et tout ce qui va bien.

    Ceci dit, le genre de code que tu montres m'a fait penser à une situation de base de donnée que l'on veut manipuler directement en C++. Et dans ce cas, faire un modèle objet me semble une abstraction totalement superflux : le modèle qui colle le plus est une séquence de tuple.

    Si la situation concrète n'est pas celle-ci, alors oui, je suis aussi pour définir une classe et des services.

    Pour l'article d'Emmanuel auquel je pense http://blog.emmanueldeloget.com/inde...ne-bonne-chose (je ne l'ai pas relu, c'est peut-être pas le bon).

Discussions similaires

  1. Perte d'enregistrements
    Par AnnSo dans le forum Paradox
    Réponses: 15
    Dernier message: 06/08/2006, 23h39
  2. [ALGO] dessiner un triangle dans le bon sens
    Par lefait dans le forum Algorithmes et structures de données
    Réponses: 13
    Dernier message: 05/02/2005, 14h38
  3. Perte de connexion (bis)
    Par rgarnier dans le forum XMLRAD
    Réponses: 7
    Dernier message: 28/05/2003, 11h14
  4. Perte du contenu des blobs
    Par macakou99 dans le forum Débuter
    Réponses: 10
    Dernier message: 22/05/2003, 15h17
  5. [UDP][Socket] perte de paquets et arret d'ecoute sur port
    Par Guismo1979 dans le forum Développement
    Réponses: 6
    Dernier message: 02/01/2003, 12h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo