Journal C(++) ?

Posté par . Licence CC by-sa
Tags :
9
29
sept.
2013

Bonjour nal,

Je t'écris aujourd'hui pour que tu m'aides à trancher une question qui me turlupine. Je suis sur le point de démarrer un projet et je n'arrive pas à choisir entre le C et le C++. Lorsque je développe en C j'ai pour habitude d’appeler mes fonctions xxx_Fonction1, xxx_Fonction2 où xxx est le nom du type (par exemple Socket_Read()).

Je souhaite aujourd'hui me lancer dans un projet où je devrai gérer de l'héritage. J’aimerais avoir ton avis sur le langage à utiliser :

  • Le C comme aujourd'hui

  • Le C avec les pointeurs de fonctions dans la structure

    struct Socket
    {
        (int)(*open)(const char * address, short port);
    };
    Socket s...;
    s.open("www.linuxfr.org",443);
    
  • Le C++

Quel est ton avis cher journal?

  • # des détails

    Posté par (page perso) . Évalué à 5.

    • pas assez de détails sur la nature du projet, sur quoi ça va tourner, etc
    • pourquoi uniquement ce choix entre C et C++ ? i y a pléthore d'autres langages…
    • Concernant le nommage des fonctions, si tu comptes faire de la POO, le C++ aura un avantage certain puisque tu bénéficieras du préfixe des classes et des namespaces. Mais le nommage est UN des critères à prendre en compte et n'est clairement pas le plus important…
    • [^] # Re: des détails

      Posté par . Évalué à 2.

      Comme détails je peux dire qu'il s'agira d'un système de GUI (d'où l'héritage pour les widgets) en réseau. Il y aura donc aussi de la programmation réseau, threads. L'objectif est de coller au maximum à la norme POSIX.

      • [^] # Re: des détails

        Posté par (page perso) . Évalué à 4.

        En fait, plutôt que de choisir un langage, on choisit plutôt des bibliothèques sous-jacentes, et souvent le choix du langage en découle. Par exemple, dans mon cas, j'utilise en général la bibliothèque Qt dès qu'il y a besoin de faire un GUI, et donc, le C++ est le choix naturel.

        Par contre, si c'est la bibliothèque Gtk qui est utilisée pour le GUI, le choix du C est possible.

        Sinon, tu as l'air de dire que tu as besoin de "gérer de l'héritage". Si tu parles de l'héritage au sens de la programmation objet, il n'y a pas vraiment matière à hésiter entre C et C++, car seul le C++ fournit des mécanismes de manipulation du concept d'héritage.

        • [^] # Re: des détails

          Posté par (page perso) . Évalué à 4.

          Pas vraiment, tu peux faire de l'héritage crado en C aussi. Exemple :

          struct A {
          ...
          };
          
          struct B {
            struct A super;
            ...
          };
          

          Et ensuite, tu peux manipuler un objet de type struct B comme si c'était un struct A avec un simple cast.

          • [^] # Re: des détails

            Posté par . Évalué à 1.

            J'avais déjà fait un test de GUI pour la SDL. Et j'avais utilisé ce genre de construction. Aujourd'hui je pose la question de pousser encore plus loin dans cette direction où d'aller vers le C++ quitte à le sous-utiliser largement.

            • [^] # Re: des détails

              Posté par (page perso) . Évalué à 0.

              Quitte à faire du C Modulaire, autant faire du C++. Sinon, c'est se compliquer la vie pour rien.

              • [^] # Re: des détails

                Posté par . Évalué à 7.

                Ça c'est un commentaire idiot. Faire du modulaire est toujours une bonne idée. Même si on parle assembleur.

                • [^] # Re: des détails

                  Posté par (page perso) . Évalué à -1.

                  Ouai, c'est comme faire du fonctionnel en C, il y a pas plus cool comme idée.

                  Enfin, essayer de réimplémenter (je dis bien « ré ») l'héritage en C, sauf pour apprendre, c'est, je le redis, ce compliquer la vie pour rien. De plus, il faut un sacré recul sur ce que l'on fait pour implémenter ce genre de chose ce que des personnes bienveillantes et techniquement meilleures que toi, moi ou l'OP on déjà fait dans ce qu'on appelle, oh wait … le C++. Après, il y a peut être confusion dans la définition de « C Modulaire ». Pour moi, elle correspond à du C+ ou le C with class (et j'ai jamais test l'objet en assembleur). Ce qui est sûr, c'est que la notion même d'héritage (comme le souligne d'autres personnes) nous mène directement C++ - à cela s'ajoute l'utilisation d'une API pour la GUI ce qui peut nous amener à Qt et tout de suite, il n'y a guère de choix.

                  PS: certains pointeront GTK pour m'expliquer qu'il existe un C+ notamment grâce au GObject, je leurs dirais que la problématique n'est pas la même et qui si l'équipe pouvait le faire en C++, il le ferait le plus tôt possible.

                  • [^] # Re: des détails

                    Posté par (page perso) . Évalué à 8.

                    La programmation modulaire au sens strict du terme n'est pas réservé qu'à la POO ou la présence de classe.
                    C'est la possibilité de faire des modules dans le code et dont l'élaboration de bibliothèque ce que le C sait faire nativement sans bidouille via des structures, des fonctions (et pointeurs de fonctions) et des fichiers séparés.

              • [^] # Re: des détails

                Posté par . Évalué à -1.

                Ya l'objective c aussi.
                Modele objet super propre, vachement moins casse gueule que le c++, des categories super utiles (grosso modo l'equivalent de mix in ruby), abi stable et non fragile, et performance tres honorables. Le runtime est libre si je ne m'abuse, clang aussi, ca marche bien, c'est rapide, et ca s'interface tres facilement avec le c ou le c++ si t'as besoin.
                Je sais pas si arc est dispo en dehors de macos/ios, mais si c'est le cas, t'as les avantages de la gestion manuelle de la memoire sans la plupart des inconvenients.

                Linuxfr, le portail francais du logiciel libre et du neo nazisme.

                • [^] # Re: des détails

                  Posté par . Évalué à 6.

                  La syntaxe d'ObjC fait saigner les yeux :/

                  • [^] # Re: des détails

                    Posté par . Évalué à -1.

                    Ca se discute. C'est du c pour 85%, donc rien de farfelu. Les named parameters sont une benediction tres honnetement, je deteste repartir sur un autre langage et me demander dans quel ordre sont ces foutus parametres. Ca rend justement le code super lisible a mon avis.
                    La dot notation s'occupe de beaucoup de cas (properties et structs).
                    Reste les [] pour les message send qui peuvent derouter. Tant que t'evites de les imbriquer (ce qui vaut aussi pour tout language soit dit en passant), ca a rien de choquant, et c'est pas si different d'une paire de parentheses.
                    Ah, et les blocks. Merci le c pour la syntaxe imbitable de pointeur se fonction.

                    C++ me parait pas franchement mieux avec ses -> & et :: a gogo

                    Linuxfr, le portail francais du logiciel libre et du neo nazisme.

          • [^] # Re: des détails

            Posté par . Évalué à 3.

            C'est la méthode qu'utilise GTK.

          • [^] # Re: des détails

            Posté par (page perso) . Évalué à 2.

            Certes, ce genre de constructions en C est possible, mais ça ne fait pas du C un langage de programmation objet pour autant. La dérivation de classes du C++ est interne au langage, alors que là, c'est de la gestion manuelle.

            Le problème des constructions manuelles, c'est qu'elles ont vite leur limite. Là, l'exemple ne marche que parce que struct A est en tête de struct B. Si on veut une structure qui hérite de deux structures, et non plus d'une seule, il va falloir faire des manipulations de pointeur horribles pour que les casts soient effectués sur les bons emplacements mémoire. Ce qui mènera probablement à un code difficile à comprendre.

            • [^] # Re: des détails

              Posté par . Évalué à 4. Dernière modification le 30/09/13 à 07:29.

              Sans compter que la vérification de l’héritage est principalement vérifié par le compilateur en C++. Avec ce genre de structure imbriquées, les vérifications qu’on peut mettre en œuvre auront lieu à l’exécution, alourdissant ainsi le programme.

            • [^] # Re: des détails

              Posté par (page perso) . Évalué à 2.

              Non mais c'était juste pour dire qu'on peut bricoler des choses. Bien sûr que si je veux faire de l'orienté objet, j'utilise un langage orienté objet (Java, C++, Python, etc.). Si tu cherches à faire des choses poussées, ça devient juste l'enfer.

  • # c++ et template

    Posté par (page perso) . Évalué à 5.

    Perso, je suis plus c++ que c…

    Une chose pas trop mal permise pas le c++ est la programmation générique. (template)

    Le but étant d'écrire une seule fonction qui comprend et agit de manière transparente selon les types. Je ne suis pas sûr que ça réponde à ce que tu cherches, mais ça permet de faire du code assez propre ( voir la biblio cgal par exemple).

    La réalité, c'est ce qui continue d'exister quand on cesse d'y croire - Philip K. Dick

  • # Ne te prends plus la tête

    Posté par (page perso) . Évalué à 3.

    Fais du Go. A moins que tu aies réellement besoin d'un de ces deux langages (gestion manuelle de la mémoire, librairies dynamiques, que sais-je encore), je te conseille vivement d'y jeter un œil. La syntaxe est faite pour rappeler beaucoup de choses à ceux qui font du C(++).

    • [^] # Re: Ne te prends plus la tête

      Posté par . Évalué à 10.

      Mouais, un des avantages de C/C++, c'est d'avoir de bonnes performances. Et bien que Go soit un langage compilé, pour l'instant la performance est plus ou moins au niveau de Java (même si il y a de bonnes chances que l'occupation mémoire soit meilleure) [1] [2]. Et tant qu'à avoir la performance de Java, j'ai envie de dire autant faire du Java qui est un langage beaucoup plus répandu (donc avec plus de bibliothèques disponibles). Oups, j'ai marché plongé dedans. Beh, j'en ai jusqu'au genou. Et on est pas du tout vendredi.

      Cela étant dit, j'ai lu que Go était très bien pour faire des applications réseau. Il contient notamment tout ce qu'il faut en standard pour faire des applications asynchrones et propose des choses sympathiques pour gérer la concurrence, ce qui est très utile quand on fait du réseau [3].

      Pour revenir plus sur le sujet de ton commentaire, ça me fait toujours tiquer quand on conseille un truc nouveau qui serait la panacée pour remplacer un truc vieux qui deviendrait par conséquent obsolète. Les nouveaux langages même s'ils apportent des améliorations très agréables n'ont pas toujours autant fait leurs preuves que les vieux machins qui sont utilisés depuis des dizaines d'années par des milliers de personnes. Ça fait qu'on peut très bien être le premier à déterrer un bug dans le compilateur/le framework qu'on utilise, qu'on a moins de documentation, etc. Personnellement, il n'y a rien qui m'horripile plus que de passer mon temps à chercher de la doc parce que la doc officielle n'est pas complète (des fois carrément lire le code source pour pallier le manque de doc), contourner des bugs ou découvrir que le compilateur ne sait pas optimiser une partie particulière de mon code.

      Dans le cas de Go, il commence à être relativement éprouvé (tu ne seras pas le premier à l'utiliser pour faire une appli réseau) mais la jeunesse relative du langage se ressent dans le manque d'optimisations du compilateur.

      [1] SO - Performance of Google Go
      [2] Loop Recognition in C++/Java/Go/Scala
      [3] Go Tour - Concurrency

      • [^] # Re: Ne te prends plus la tête

        Posté par . Évalué à 1.

        Je me dirige plutôt vers un langage ayant fait ses preuves, simple, souple et connu de la majorité des développeurs (encore que…), c'est pour ça que le C me convient et que j'aimerais le garder. D'un autre coté le C++ offre plus de possibilité mais je n'en ai pas forcément besoin…

        • [^] # Re: Ne te prends plus la tête

          Posté par . Évalué à 4.

          Bof, de nos jours, C++ a aussi fait ses preuves, est souple et connu de la majorité de développeurs. Bon après ce n'est pas vraiment un langage simple (malheureusement), il y a beaucoup (trop ?) de fonctionnalités et constructions syntaxiques (je pense aux classes/fonctions amies, héritage privé etc.), et il y a pas mal de pièges du fait du mélange de la programmation orientée objet et de la gestion manuelle de la mémoire.

          Ahma, si tu veux faire de la POO extensivement, tu as besoin de C++. C n'est pas vraiment adapté pour faire de la POO.

          • [^] # Re: Ne te prends plus la tête

            Posté par (page perso) . Évalué à 3.

            Je trouve aussi le C++ compliqué, mais après tu peux aussi ne pas tout utiliser : tu peux aussi te contenter de faire, en gros, du "C with classes" (y'en a peut-être qui vont dire que c'est MAL, mais je trouve pas ça absurde).

            Après si c'est un projet perso je pense que c'est logique de prendre aussi en compte les éléments subjectifs, du genre est-ce que tu as plutôt envie de réfléchir à comment faire de l'héritage ou de l'objet en C (ce qui peut être un peu galère, mais que je trouve formateur) ou d'apprendre un nouveau langage ?

            • [^] # Re: Ne te prends plus la tête

              Posté par . Évalué à 2.

              C'est un projet perso c'est pour ça que je me pose la question. Je pense aussi que recréer un mécanisme d'héritage simple serait à la fois formateur et m'éviterais de sortir l'artillerie lourde avec le C++. Donc soit je sous-utilise fortement le C++ soit j'ajoute un peu de complexité à mon code pour ajouter l'héritage simple.

        • [^] # Re: Ne te prends plus la tête

          Posté par . Évalué à 1.

          Je ne suis pas d'accord en C, tu peux controller le design de ton modele objet. Alors qu'en C++, il t'est impose. Le C++ t'offre plus de facilite, pas plus de possibilite.

          • [^] # Re: Ne te prends plus la tête

            Posté par (page perso) . Évalué à 9.

            Faux!
            Tu contrôles bien plus le design de ton object en C++ car tout est possible. Tu as le choix entre plein de méthode

            struct MyClass {
               // le plus classique, une fonction virtuelle
                virtual int myVirtualFunction(double);
              // un pointeur de fonction comme en C
                int (*myPointer)(double);
              // une table virtuel manuelle
               struct VTable {
                     int (*firstFunction)(double)
               };
                VTable *vtable;
            
              // boost::signals
                signals<int(double)> mySignal;
              // Qt signals (c'est tricher?)
              signals:  int myQtSignal(double);
            };
            
            /* et enfin, le static polymorphise via le Curiously recurring template pattern  qui a l'avantage d'être plus performent car il peux inliner les appels.  Vas-y pour faire ça en C */
            template<class Derived> struct Base {
              int myFunction(double a) 
              { return static_cast<Derived*>(this)->myFunction(a); }
            };

            Bref, plein de possibilité offerte en C++, chacune adaptée à son usage. Mais dans tout les cas, la manière de faire en C++ est moins fastidieuse, plus facile à écrire et relire, et moins prône à l'erreur.

            Bref, le C est un mauvais choix.

            • [^] # Re: Ne te prends plus la tête

              Posté par . Évalué à 1.

              Tu peux me pointer ce qu'on ne peut pas coder en C, s'il te plait ? Parce que la ca me parait pas bien compliquer de faire des fonctions virtuelles, un pointeur sur fonction, ou une table de pointeur sur fonctions partage, des signaux et une macro :-)

              • [^] # Re: Ne te prends plus la tête

                Posté par (page perso) . Évalué à 6.

                Ce que tu pourrais faire en C est bien plus fastidieux, demande beaucoup plus de code boiler plate et est beaucoup plus prône à l'erreur que du code en C++

                • [^] # Re: Ne te prends plus la tête

                  Posté par . Évalué à 2.

                  « … prône à l'erreur… »

                  Ça ne fait pas de sens ton expression !

                  Et plus dans le cœur du débat : on peux faire des trucs bien puissants en C++ de manière très concise, mais d'une part les erreurs sont moins fréquentes mais plus dangereuses (cf. première citation) et d'autre part les messages d'erreur remonté par le C++ sont fréquemment incompréhensible et demandent pas mal de recherche avant de pouvoir les corriger.

                  Ce qui me porterait donc à conseiller le C à quelqu'un qui hésite avec le C++, un peu comme un type qui devant couper une branche se demande si il prend sa scie ou une tronçonneuse car il a entendu dire que c'était plus rapide dans le second cas.

                  • [^] # Re: Ne te prends plus la tête

                    Posté par . Évalué à 6.

                    d'autre part les messages d'erreur remonté par le C++ sont fréquemment incompréhensible et demandent pas mal de recherche avant de pouvoir les corriger.
                    Faux à double titre :
                    1. c'est tout au plus une remarque de débutant ; avec l'expérience, les erreurs ne sont plus incompréhensibles.
                    2. aujourd'hui les compilateurs modernes (GCC et en particulier clang) on a des informations très précises et bien plus utiles qu'avant sur l'erreur (notamment, tous les templates ne sont pas toujours déroulés). Un petit coup de google pour les cas les plus problématiques le cas échéant, et hop on comprend, à défaut de résoudre si on était parti sur un truc impossible à faire avec le langage.

                  • [^] # Re: Ne te prends plus la tête

                    Posté par (page perso) . Évalué à 1.

                    Je voulais évidemment dire moins prone a l' erreur.

                    Tu as raison à propos de la tronçonneuse, mais le C est tout aussi dangereux, si pas plus. Ce qu'il faut conseiller à un débutant c'est un language comme Python.

                    Et pour les erreurs incompréhensible, tu as essayé un compilateur recent? Il y a eu beaucoup de progrès ces dernières années, notamment grâce à clang

                    • [^] # Re: Ne te prends plus la tête

                      Posté par (page perso) . Évalué à 5.

                      Je voulais évidemment dire moins prone a l' erreur.

                      Ah bon, pas sujet à l'erreur ou enclin à l'erreur ?

                    • [^] # Re: Ne te prends plus la tête

                      Posté par . Évalué à 5.

                      Bon je me permets d'insister parce que c'est vraiment atroce :
                      « prone à » (de même que « faire du sens ») n'est pas français. Ça pourrait être un détail mais je l'ai je ne sais combine de fois dans ce journal… et mon message d'erreur n'était pas très clair.

                      Sur les messages C++, il est dommage que je n'en ai pas un petit sous la main, mais je pense en particulier à l'appel d'une fonction avec un paramètre ayant le mauvais type. Entre la fonction qui peut être surchargée, la classe du paramètre qui peut définir des opérateurs de conversion, le tout passé en référence et des éventuels petits const en prime, on se retrouve dans un mélimélo complétement incompréhensible.

                      Je n'ai pas de doute que des furieux du C++ peuvent désemberlificoter ça en moins de 3h, mais le même genre de problème en C n'a jamais pris plus de 30s.

                      • [^] # Re: Ne te prends plus la tête

                        Posté par (page perso) . Évalué à 3.

                        Entre la fonction qui peut être surchargée, la classe du paramètre qui peut définir des opérateurs de conversion, le tout passé en référence et des éventuels petits const en prime, on se retrouve dans un mélimélo complétement incompréhensible.

                        Pour bien faire il aurait fallu ajouter un spécialisation de template. :)

                        Tu as complètement raison, il n'y a aucune commune mesure entre la complexité des messages du C++ et de ceux du C.

                        • [^] # Re: Ne te prends plus la tête

                          Posté par (page perso) . Évalué à 3.

                          Ouais, faut être honnête, j'aime beaucoup le C++, mais Gof exagère un peu, tout de même :)
                          Pratiquant régulièrement les deux (C et C++), on peut rapidement se retrouver à relire 5 fois un message d'erreur C++ avant que ça fasse tilt…

                • [^] # Re: Ne te prends plus la tête

                  Posté par . Évalué à 1.

                  Ca je n'ai pas dit le contraire. Maintenant il y a des constructions par exemples sur l'heritage multiple que tu ne peux pas faire en C++, mais que tu peux coder en C. Par contre, le boiler plate sera clairement plus long a creer. Mais ca a un avantage, celui-ci sera plus explicite.

              • [^] # Re: Ne te prends plus la tête

                Posté par . Évalué à 3.

                Tu le fait avec des vérifications statiques de type ? Je pense que ça deviens très vite barbant.

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

          • [^] # Re: Ne te prends plus la tête

            Posté par . Évalué à -1.

            Le C++ t'offre plus de facilite, pas plus de possibilite.

            Le C++ t'offre plus de possibilite, pas plus de facilite.

      • [^] # Re: Ne te prends plus la tête

        Posté par (page perso) . Évalué à 4.

        Oh, tu as sauté dedans à pieds joints :)

        Au moment où j'ai écrit ce commentaire, je n'avais aucune idée de ce que EmilienR< voulait faire. Maintenant que je sais qu'il est question de UI, effectivement, faire du go n'est pas une bonne idée. De manière plus générale, c'était une proposition pour essayer un nouveau langage en même temps qu'il commençait un nouveau projet (c'est toujours intéressant de voir ailleurs, ne serait-ce que pour dire que l'herbe est finalement plus verte ici).

        Et bien que Go soit un langage compilé, pour l'instant la performance est plus ou moins au niveau de Java

        Je ne conseille pas le Go pour ses performances (qui sont tout de même particulièrement bonnes), mais plutôt pour:

        • sa facilité d'apprentissage (je suis peut-être biaisé, mais on pourrait comparer sa facilité d'apprentissage à python)
        • sa gestion built-in de la concurrence qui est un vrai bonheur à utiliser (surtout le fait de ne pas avoir à s'en soucier)
        • sa rapidité de compilation qui le rapproche, pour la phase de développement, d'un langage interprété
        • sa facilité de déploiement (qui peut clairement être un défaut pour d'autres, vu qu'il s'agit tout simplement de tout compiler en statique dans un gros binaire …)
        • sa libraire standard déjà bien large
        • sa gestion des dépendances incluse dans le package qui va avec le langage

        En fait, c'est comme pour systemd et la vitesse de boot: c'est pas la raison qui fait switcher, mais c'est un après-coup bien appréciable.

        Pour revenir plus sur le sujet de ton commentaire, ça me fait toujours tiquer quand on conseille un truc nouveau qui serait la panacée pour remplacer un truc vieux qui deviendrait par conséquent obsolète.

        Je l'avoue, j'ai peut-être été un peu fort en disant "Ne te casse plus la tête". Disons que j'ai été pas mal impressionné de voir un certain nombre de boites et autres grosses structures migrer certains de leurs outils en go en un temps record (pour des gens qui ne connaissaient pas le langage) et mettre ça en production (cf cette liste, par exemple) du coup j'ai tendance à croire que la qualité est là. Mais oui, c'est sûr, C et C++ sont loin d'être deprecated, il y a encore beaucoup de bonnes raisons qui font qu'ils restent des langages à considérer.

    • [^] # Re: Ne te prends plus la tête

      Posté par . Évalué à 6.

      gestion manuelle de la mémoire
      En même temps, en C++, on évite au maximum de gérer la mémoire à la main (new, delete, etc). Ce n'est pas inutile dans certains cas, mais contrairement au C où on passe son temps à allouer des objets, les passer par pointeur, et à fournir la taille des tableaux, en C++ c'est facile et transparent une fois la classe de base (ou les classes de la bibliothèque standard o du toolkit) écrite.
      De même en C++, les références sont explicites, ce qui s'apparente à une gestion manuelle de la mémoire, mais à part à quelques endroits judicieusement placés, on les utilise intuitivement aux passages d'arguments dans des fonctions.

  • # C avec les pointeurs de fonctions dans la structure

    Posté par . Évalué à 4. Dernière modification le 29/09/13 à 17:52.

    Honnêtement, je vois pas trop l'intérêt de faire de la pseudo-programmation orientée objet avec des pointeurs de fonction dans les structures, mais peut-être que quelqu'un pourra m'éclairer dans la suite des commentaires. Ça me semble être un détournement de l'outil utilisé (le langage C) pour faire des choses beaucoup plus faciles à faire avec un langage plus adapté (le langage C++). Encore, je peux concevoir que ça avait un intérêt à une époque où les compilateurs C++ étaient moins optimisés/moins disponibles que les compilateurs C.

    Tu as précisé dans les commentaires que tu allais également programmer un GUI dans cette applications. Si tu utilises un framework C++ (au hasard Qt), j'aurais tendance à te conseiller de programmer également avec un style C++, ça te rendra la vie beaucoup plus facile. Si tu utilises un framework C (GTK+ ?), tu peux éventuellement rester en C, même si ça devrait bien s'utiliser en C++ aussi.

  • # Vala ?

    Posté par (page perso) . Évalué à 9. Dernière modification le 29/09/13 à 18:03.

    Si j'ai bien compris tu veux un truc très proche du C mais qui te permette de gérer de l'héritage proprement.

    Pourquoi ne pas essayer Vala ? C'est un langage à syntaxe style C# qui se compile en C (avec une norme bien définie et stable de nommage, ce qui permet d'écrire des bibliothèques C en Vala tout en ayant une API propre).
    Tu as à disposition tout l'univers de la GLib, une domumentation très correcte (Vala Tutorial, Valadoc) et la possibilité de créer des bindings vers d'autres langages facilement (via GObject Introspection).

    De plus comme ça se compile en C, tu peux assez facilement l'associer à du code C ou C++ (en utilisant ton code Vala compilé dans du code C ou C++, ou en appelant du code C depuis ton code Vala).
    Par contre pour rester très compatible avec le C, il ne gère la surcharge de fonction ou d'opérateur.

    Par défaut ça utilise GObject mais si cette idée te déplaît tu peux demander à valac (le compilateur Vala -> C) d'utiliser le profil POSIX à la place : https://wiki.gnome.org/Vala/Tutorial#Profiles (cependant je t'avoue que je ne sais pas ce que ça signifie concrètement, faudrait que je sorte du code C en utilisant les deux profils pour comparer…).

    • [^] # Re: Vala ?

      Posté par . Évalué à 2.

      C'est un piste à laquelle je n'avais pas pensé, je lirai la doc ce soir je pense! Merci

    • [^] # Re: Vala ?

      Posté par . Évalué à 1.

      Oui mais Vala, c'est GObject et en plus le debuggage est pas facile. J'aime beaucoup Vala (j'ai écrit GNOME Scan en Vala…) mais c'est pas très mûr. C'est bien encore d'être à l'aise avec C/GObject quand on fait du Vala.

      • [^] # Re: Vala ?

        Posté par (page perso) . Évalué à 2.

        Oui mais Vala, c'est GObject

        Justement, as-tu déjà essayé le profil POSIX ? J'ai pas la moindre idée de ce que c'est supposé faire, j'ai fait un test hier, espérant pouvoir comparer le code C produit par rapport à l'habituel, mais il n'a pas compilé (c'était pourtant un simple "hello world", il doit me manquer le profil POSIX en question).

        et en plus le debuggage est pas facile.

        C'est vrai que le compilateur a tendance à trouver les erreurs quelques lignes à côté du problème réel… c'est assez déstabilisant au début.
        Je n'ai pas la moindre idée de la facilité à déboguer du Vala, n'ayant jamais vraiment utilisé d'outils comme GDB ou Valgrind…

        J'aime beaucoup Vala (j'ai écrit GNOME Scan en Vala…) mais c'est pas très mûr. C'est bien encore d'être à l'aise avec C/GObject quand on fait du Vala.

        De bonnes bases en C et GObject sont dispensables pour une utilisation occasionnelle, mais si on veut profiter pleinement de Vala, c'est clair qu'il vaut mieux les apprendre.

        Après tout Vala a été conçu pour ça : être un langage clair et simple qui a une grande capacité d'interfaçage avec C et GObject. Je trouve que ça fait de Vala un langage très adapté à la programmation système haut niveau (applications graphiques par exemple). Vivement Vala 1.0. =)

        • [^] # Re: Vala ?

          Posté par . Évalué à 0.

          Tiens oui, j'avais oublié le profil POSIX. Merci :-) Mais à mon avis, c'est surtout une preuve de principe.

          Y'a-t-il des logiciels non-GNOME qui utilisent Vala ?

          • [^] # Re: Vala ?

            Posté par (page perso) . Évalué à 4.

            Beaucoup (sinon tous) des logiciels elementary, mais comme ils se reposent énormément sur les bibliothèques GNOME dans leur ensemble, ils sont en quelque sorte cousins de GNOME.

            Il doit bien y en avoir quelques uns mais c'est pas évident de les découvrir en effet.

  • # Pour gérer l'héritage

    Posté par . Évalué à 10.

    Fais confiance à un notaire…

    • [^] # Re: Pour gérer l'héritage

      Posté par . Évalué à 3.

      Oh merde tu m'ouvres les yeux là! Je pense que c'est ce que je vais faire. Journal résolu :D!

      (tu peux sortir discrètement, la clé est sous le nain de jardin)

  • # Tout sauf C++

    Posté par (page perso) . Évalué à -2.

    Si c'est possible évite d'éviter C++ pour ton projet. Les raisons qui pourraient te faire choisir C++ sont:

    • ton chef;
    • ton client;
    • tu connais C++, tu ne veux pas apprendre un nouveau langage et ton projet est trop complexe pour être raisonnablement réalisé en C;
    • tu veux consolider tes compétences en C++ pour contribuer à un projet C++.

    Si aucune de ces affirmations n'est vraie, alors choisis un autre langage, qui est vraiment de haut niveau.

    Je suis plutôt pour OCaml ou Common-Lisp mais d'autres ont suggéré des langages que je ne connais pas (Vala, Go, etc.) qui peuvent t'attirer. J'ai déjà mené à bien un moyen projet (6 mois) en Python et justement, pour les moyens projets, je ne te le recommenderais pas.

    • [^] # Commentaire supprimé

      Posté par . Évalué à 0.

      Ce commentaire a été supprimé par l'équipe de modération.

      • [^] # Re: Tout sauf C++

        Posté par (page perso) . Évalué à 5.

        C'est vrai que le noyaux linux est trop complexe pour être réalisé en C.

        Il y a plein de sortes de complexités. Puisque dans la question de EmilienR il y a écrit

        Je souhaite aujourd'hui me lancer dans un projet où je devrai gérer de l'héritage. J’aimerais avoir ton avis sur le langage à utiliser

        on peut largement déconseiller le C dans ce cas de figure pour les relations d'héritage complexe.

        Sinon des logiciels complexes au sens large écrits en C, il y en a une paire effectivement.

        • [^] # Commentaire supprimé

          Posté par . Évalué à 3.

          Ce commentaire a été supprimé par l'équipe de modération.

          • [^] # Re: Tout sauf C++

            Posté par . Évalué à 0.

            mais en OO, mais on l'implémente parfois par un rectangle est un carré car un rectangle possède des caractéristiques supplémentaires
            En même temps, il serait absurde de faire hériter carré de rectangle puisque, comme tu dis, un carré est un rectangle contraint (longueur = largeur), donc avec un paramètre de moins.
            L'analogie "est un" n'est qu'une analogie, qui ne marche pas dans tous les cas.

            • [^] # Commentaire supprimé

              Posté par . Évalué à 4.

              Ce commentaire a été supprimé par l'équipe de modération.

              • [^] # Re: Tout sauf C++

                Posté par . Évalué à 2.

                Bien sûr. Ce sont donc obligatoirement deux objets bien distincts, avec leur méthodes propres pour calculer l'aire, etc.
                C'est d'autant plus clair si on cherche à faire une hiérarchie de classes avec, mettons, les parallélogrammes et les losanges. Les prédicats sont complètement différents d'un losange à un rectangle, et donc à un carré.

                • [^] # Re: Tout sauf C++

                  Posté par . Évalué à -1.

                  C'est intéressant ce que vous dites, ça me fait penser à la théorie des groupes.

          • [^] # Re: Tout sauf C++

            Posté par (page perso) . Évalué à 2.

            Sur le fond je suis complètement d'accord avec toi, seulement, je ne présente pas du tout l'héritage, donc en particulier pas de façon biaisée, et au contraire de toi

            (Est-ce que l'héritage est la bonne façon de voir les choses ?).

            j'ai répondu à EmilienR en essayant de lui apportant les informations qu'il demandait:

            Je souhaite aujourd'hui me lancer dans un projet où je devrai gérer de l'héritage. J’aimerais avoir ton avis sur le langage à utiliser :
            [ C, C++, C avec table de méthodes à la mano]

            Mais dans un autre cadre j'aurais pu écrire la même chose que toi.

          • [^] # Re: Tout sauf C++

            Posté par . Évalué à 4.

        • [^] # Re: Tout sauf C++

          Posté par . Évalué à 2.

          « on peut largement déconseiller […] les relations d'héritage complexe.»

          En fait je suis d'accord.

  • # Sans pointeurs de fonction

    Posté par . Évalué à 3. Dernière modification le 29/09/13 à 21:27.

    Salut,

    Je ne t'aiderais pas pour ce qui est du choix entre le C et le C++ ne connaissant pas suffisamment le second ; par contre, si tu choisis le C, je te déconseille d'utiliser des pointeurs de fonctions dans l'objectif de simuler de la POO. D'une part le code devient redondant puisque tu dois passer une référence vers la structure à la fonction appelée et, d'autre part, tu vas gaspiller de la mémoire puisque chaque structure contiendra x pointeurs de fonctions.

    • [^] # Re: Sans pointeurs de fonction

      Posté par (page perso) . Évalué à 1.

      D'une part le code devient redondant puisque tu dois passer une référence vers la structure à la fonction appelée

      En quoi est-ce redondant ? En C++, le langage le fait pour nous, et c'est le pointeur this. En C, il faut le faire manuellement.

      tu vas gaspiller de la mémoire puisque chaque structure contiendra x pointeurs de fonctions.

      Tout dépend de comment est fait la structure. Si dans la structure, tu copies tous les pointeurs de fonction, alors oui, il y a gaspillage de mémoire. Maintenant, si dans la structure, tu mets un pointeur vers une autre structure contenant l'ensemble des pointeurs de fonction, alors non, il n'y a pas de perte de place, car il y aura alors une seule structure de pointeurs par "classe" et chaque occurrence de la classe pointera sur cette structure. Il me semble d'ailleurs (à confirmer), que c'est ce mécanisme qui est utilisé en C++ (en plus compliqué pour pouvoir gérer l'héritage multiple).

      • [^] # Re: Sans pointeurs de fonction

        Posté par . Évalué à 2.

        Dans ce cas je ne vois pas l'intérêt, autant appeler directement les fonctions…

        • [^] # Re: Sans pointeurs de fonction

          Posté par (page perso) . Évalué à 5.

          L'intérêt ? Le polymorphisme. Chose que tu ne pourras pas avoir en appelant directement la fonction, puisque la "résolution" de la fonction se fait à la compilation et que le polymorphisme impose une résolution dynamique (i.e., durant l'exécution).

          • [^] # Re: Sans pointeurs de fonction

            Posté par (page perso) . Évalué à 3.

            Je ne vois pas le rapport entre le polymorphisme et le côté dynamique. D'autant plus que le C++ permet le polymorphisme alors que là aussi tout est géré à la compilation.
            Si tu veux du polymorphisme en C, il y a moyen de ruser pour y parvenir. Tu prends deux structures qui ont en commun une fonction avec le même nom (et la même propriété, comme le calcul d'une aire d'une surface) via des pointeurs de fonctions et en réalisant des fonctions static tu peux isoler ces fonctions de sorte à éviter la collision des noms malgré la présence des deux structures et tu as ton polymorphisme.

            Je n'ai pas testé en vrai mais je pense que la piste est bonne, en tout cas il me semble bien que GTK+ arrive en C à gérer ce cas de figure.

            • [^] # Re: Sans pointeurs de fonction

              Posté par (page perso) . Évalué à 1.

              Je me rends compte qu'utiliser le mot "résolution" dans mon précédent commentaire n'était peut être très futé. Mea culpa. Lorsque je parle de résolution, je parle de savoir quelle est la fonction qui va être appelée (et aucunement la résolution des noms comme peut le faire un éditeur de lien).

              Pour reprendre ton exemple sur les aires :

              abstract class FormeGeometrique
              {
                 public:
                    virtual float aire();
              }
              
              class Carre : public FormeGeometrique
              {
              ...
              }
              
              class Cercle : public FormeGeometrique
              {
              ...
              }
              
              ...
              
              int aireFoisDeux(FormeGeometrique* forme)
              {
                 return forme->aire() * forme->aire();
              }

              Ici, dans ma fonction aireFoisDeux, j'appelle la méthode aire() de l'objet passé en paramètre. Au moment de la compilation, le compilateur ne peut pas savoir si c'est la méthode aire de la classe Carre ou celle de la classe Cercle qui va être appelée, d'autant plus que cela peut changer d'un appel à l'autre en fonction de la nature de l'objet passé en paramètre. C'est en cela que c'est dynamique. Le C++ fait cela pour nous de manière transparente, en utilisant une table des méthodes virtuelles, qui n'est rien d'autre qu'une table de pointeur (la fameuse vtable manquante si on oublie de déclarer le destructeur comme étant virtuel par exemple ;)). En C, il faut faire cela à la main, en gérant des pointeurs de fonctions.

              Enfin, tu noteras que l'explication que tu donnes sur la manière d'avoir du polymorphisme en C est exactement la même que celle proposée par Taurre, avec comme inconvénient un certain gaspillage de la mémoire proportionnelle au nombre de méthodes virtuelles.

              • [^] # Re: Sans pointeurs de fonction

                Posté par (page perso) . Évalué à 0.

                C'est en cela que c'est dynamique. Le C++ fait cela pour nous de manière transparente, en utilisant une table des méthodes virtuelles, qui n'est rien d'autre qu'une table de pointeur (la fameuse vtable manquante si on oublie de déclarer le destructeur comme étant virtuel par exemple ;)). En C, il faut faire cela à la main, en gérant des pointeurs de fonctions.

                Je t'ai dis uniquement que c'était possible en C, pas que c'était aussi simple qu'en C++.
                En gros il est possible de retrouver un C avec la plupart des éléments de la POO mais cela demande de gros efforts et c'est plus tordu à réaliser qu'en C++. Mais c'est possible.

                Je suis d'accord donc sur le fait d'éviter de simuler la POO avec du C dans la mesure du possible car le C++ offre un confort intéressant de ce côté là.

                Enfin, tu noteras que l'explication que tu donnes sur la manière d'avoir du polymorphisme en C est exactement la même que celle proposée par Taurre, avec comme inconvénient un certain gaspillage de la mémoire proportionnelle au nombre de méthodes virtuelles.

                Il est peut être possible de régler ce problème, je n'ai pas trop réfléchi à cette question de consommation de ce côté.
                Note aussi qu'on peut contourner la difficulté, par exemple ta fonction précédente pourrait être refaite pour prendre en paramètre l'aire en non une figure géométrique pour retomber sur tes pattes car l'appel de fonction sera facilement traité par l'éditeur de liens par exemple.

                Je suis conscient que c'est tordu après. Mais certains le font (j'ai un peu regarder la Win API et GTK de ce côté).

                • [^] # Re: Sans pointeurs de fonction

                  Posté par (page perso) . Évalué à 3.

                  Je t'ai dis uniquement que c'était possible en C, pas que c'était aussi simple qu'en C++.

                  Je répondais surtout à "Je ne vois pas le rapport entre le polymorphisme et le côté dynamique" ;) Après, depuis le début, je dis que c'est possible en C (j'ai même proposé une alternative à la méthode de Taurre pour économiser de la mémoire). Relis bien les commentaires, tout est déjà présent depuis le premier commentaire !

                  Note aussi qu'on peut contourner la difficulté, par exemple ta fonction précédente pourrait être refaite pour prendre en paramètre l'aire en non une figure géométrique pour retomber sur tes pattes car l'appel de fonction sera facilement traité par l'éditeur de liens par exemple.

                  C'est une fausse solution (et pas toujours applicable). L'idée derrière la POO (outre l'héritage et la mise en commun de code) c'est aussi de pouvoir penser en niveaux d'abstraction. Dès lorsque je dispose d'une abstraction, alors je peux manipuler tout un tas d'objet derrière. Ici, ce qui m'importe, c'est la notion d'objet géométrique. Peu m'importe que ce soit un carré, un rectangle, un cercle ou tout autre figure fermée pour laquelle il est possible de calculer une aire.

                  Je peux donc écrire des pans entiers d'algorithme en ne travaillant qu'au niveau de cette abstraction sans connaître exactement les objets que je manipule. Hors, avec ce que tu proposes, tu sous-entends que l'appelant de la fonction airefois2 dispose de cette connaissance. Parfois, ce sera le cas, parfois non.

                  Je suis conscient que c'est tordu après. Mais certains le font (j'ai un peu regarder la Win API et GTK de ce côté).

                  J'ai pas mal regardé l'API Win32 dans mon enfance et un peu celle de GTK, et je ne vois absolument pas où cette approche que tu décris est employée. As-tu un exemple sous la main pour étayer ? :)

      • [^] # Re: Sans pointeurs de fonction

        Posté par . Évalué à 2.

        Francesco a écrit:

        En quoi est-ce redondant ? En C++, le langage le fait pour nous, et c'est le pointeur this. En C, il faut le faire manuellement.

        Je veux dire par là que la référence vers la structure est utilisée deux fois : d'abord pour obtenir le champ souhaité, ensuite comme argument de la fonction appelée. En bref, cela donne par exemple ceci :

        s.open(&s, "www.linuxfr.org",443);

        s est utilisé deux fois.

        Francesco a écrit:

        Tout dépend de comment est fait la structure. Si dans la structure, tu copies tous les pointeurs de fonction, alors oui, il y a gaspillage de mémoire. Maintenant, si dans la structure, tu mets un pointeur vers une autre structure contenant l'ensemble des pointeurs de fonction, alors non, il n'y a pas de perte de place, car il y aura alors une seule structure de pointeurs par "classe" et chaque occurrence de la classe pointera sur cette structure.

        En effet, c'est une solution envisageable, mais le code sera nettement moins lisible.

        s.method->open(&s, "www.linuxfr.org",443);
        

        Francesco a écrit:

        L'intérêt ? Le polymorphisme. Chose que tu ne pourras pas avoir en appelant directement la fonction, puisque la "résolution" de la fonction se fait à la compilation et que le polymorphisme impose une résolution dynamique (i.e., durant l'exécution).

        Il est tout à fait possible d'utiliser le polymorphisme en C sans utiliser massivement les pointeurs de fonctions. En fait, ils ne sont nécessaire que pour les fonctions virtuelles. Pour reprendre ton exemple, en C, cela donne :

        #include <stdio.h>
        #include <stdlib.h>
        
        struct forme_geometrique {
            struct forme_geometrique_vtable *vtable;
        };
        
        struct forme_geometrique_vtable {
            float (*area)(void *);
        };
        
        struct carre {
            struct carre_vtable *vtable;
            float len;
        };
        
        struct carre_vtable {
            struct forme_geometrique_vtable super;
        };
        
        struct circle {
            struct circle_vtable *vtable;
            float radius;
        };
        
        struct circle_vtable {
            struct forme_geometrique_vtable super;
        };
        
        extern struct carre *carre_create(float);
        extern void carre_destroy(struct carre *);
        extern float carre_area(void *);
        extern struct circle *circle_create(float);
        extern void circle_destroy(struct circle *);
        extern float circle_area(void *);
        extern float forme_geometrique_area(void *);
        
        
        struct carre *
        carre_create(float len)
        {
            static struct carre_vtable vtable = { { &carre_area } };
            struct carre *self;
        
            self = malloc(sizeof *self);
            if (self == NULL) {
                return NULL;
            }
            self->vtable = &vtable;
            self->len = len;
            return self;
        }
        
        
        void
        carre_destroy(struct carre *self)
        {
            if (self != NULL) {
                free(self);
            }
        }
        
        
        float
        carre_area(void *p)
        {
            struct carre *self;
        
            self = p;
            return self->len * self->len;
        }
        
        
        struct circle *
        circle_create(float radius)
        {
            static struct circle_vtable vtable = { { &circle_area } };
            struct circle *self;
        
            self = malloc(sizeof *self);
            if (self == NULL) {
                return NULL;
            }
            self->vtable = &vtable;
            self->radius = radius;
            return self;
        }
        
        
        void
        circle_destroy(struct circle *self)
        {
            if (self != NULL) {
                free(self);
            }
        }
        
        
        float
        circle_area(void *p)
        {
            struct circle *self;
            float const pi = 3.14F;
        
            self = p;
            return self->radius * self->radius * pi;
        }
        
        
        float
        forme_geometrique_area(void *p)
        {
            struct forme_geometrique *self;
        
            self = p;
            return self->vtable->area(p);
        }
        
        
        int
        main(void)
        {
            struct carre *carre;
            struct circle *circle;
        
            carre = carre_create(4);
            circle = circle_create(3.5);
            if (carre == NULL || circle == NULL) {
                return EXIT_FAILURE;
            }
            printf("%f\n", forme_geometrique_area(carre));
            printf("%f\n", forme_geometrique_area(circle));
            carre_destroy(carre);
            circle_destroy(circle);
            return 0;
        }
        • [^] # Re: Sans pointeurs de fonction

          Posté par (page perso) . Évalué à 1.

          s.open(&s, "www.linuxfr.org",443);

          Ok, je vois ce que tu veux dire. Et je ne peux que te dire que tu as entièrement raison ;)

          Il est tout à fait possible d'utiliser le polymorphisme en C sans utiliser massivement les pointeurs de fonctions. En fait, ils ne sont nécessaire que pour les fonctions virtuelles

          Tout à fait. Sans les fonctions virtuelles, point de polymorphisme. Par contre, on peut toujours profiter de l'héritage (mais qui perd pas mal de sens sans cette notion).

    • [^] # Re: Sans pointeurs de fonction

      Posté par . Évalué à 3.

      C'est en parti ce qui me gène avec le fait de stocker les pointeurs de fonctions dans la structure. Dans certains cas la "charge utile" doit être relativement faible. Pour un socket par exemple il faut (au moins) 7 fonctions :

      • free (libération)
      • connect
      • close
      • read
      • write
      • setsockopt
      • getsockopt

      avec comme donnée :

      • file_descriptor : int

      Sur un système 64bits on a donc 7*8 = 56 octets pour les pointeurs de fonctions contre 4 pour les données. Je trouve qu'on perd énormément de place pour par grand chose.

      • [^] # Re: Sans pointeurs de fonction

        Posté par (page perso) . Évalué à 2.

        Ou pour reprendre ce que je disais dans mon commentaire ci-dessus, l'utilisation d'une structure stockant les fonctions liées à une classe (appelons cette structure vtable :)), fait baisser la consommation mémoire de 56 à 8 octets, et ceci, quel que soit le nombre de fonction présentes. Par contre, il est vrai que cette approche à un coût car nécessite une indirection supplémentaire.

  • # Oublies le C.

    Posté par (page perso) . Évalué à 9.

    Il est aujourd'hui ridicule de choisir le C face au C++. Je m'explique: Le C++ étant multi-paradigmes, it est à la fois de bas niveau et de haut niveau. Prenant le meilleur des deux mondes.

    En C, tu es forcément limité à gérer la mémoire de façon manuelle, fastidieuse et prône à l'erreur. (crash, leak).
    En C++, tu as l'aide des destructeurs et des smart pointers et tu codes bien plus vite sans te tracasser de bien faire tout tes free(). En C, chaque fois que tu veux une structure de donnée simple, tu dois tout refaire à la main, alors que en C++ tu disposes des structures de donnée de base dans les bibliothèque standard quasi aussi performantes que celle que tu pourais faire à la main. (Et pour les rare cas où de structures de donnée plus compliquées ou plus perfomantes, tu peux toujours les faire à la main comme en C).

    La bibliothèque standard du C++ est déjà bien fournie. Mais tu peux aussi utiliser Qt ou boost qui sont de bonnes bibliothèques. Et toutes les bibliothèques C sont aussi accessible via C++.

    Si tu trouves que le C++ est trop compliqué, tu n'est pas obligé d'utiliser les exceptions ou des templates dans ton application.

    Ma recommandation est donc d'utiliser C++, y compris les nouveauté de C++11 tel que auto ou les fonctions lambda.

    • [^] # Re: Oublies le C.

      Posté par (page perso) . Évalué à 1. Dernière modification le 29/09/13 à 22:38.

      Il est aujourd'hui ridicule de choisir le C face au C++. Je m'explique: Le C++ étant multi-paradigmes, it est à la fois de bas niveau et de haut niveau. Prenant le meilleur des deux mondes.

      Non, comparé à C++, le C est un langage simple et cohérent — c'est dire l'état de C++!

      Si tu trouves que le C++ est trop compliqué, tu n'est pas obligé d'utiliser les exceptions

      Tu conseilles d'utiliser la forme de new qui renvoie des NULL?

      ou des templates dans ton application.

      Dans ce cas, ça va être assez dur d'utiliser la biblitohèque standard, boost ou Qt, comme tu lui suggères:

      La bibliothèque standard du C++ est déjà bien fournie. Mais tu peux aussi utiliser Qt ou boost qui sont de bonnes bibliothèques. Et toutes les bibliothèques C sont aussi accessible via C++.

      • [^] # Re: Oublies le C.

        Posté par (page perso) . Évalué à 8.

        comparé à C++, le C est un langage simple et cohérent

        Un boulier compteur est plus « simple et cohérent » qu'une calculatrice électronique. Mais je préfère utiliser une calculatrice.

        Tu conseilles d'utiliser la forme de new qui renvoie des NULL?

        C'est un autre sujet, mais, en fonction du type d'application, je conseil de ne pas geré de cas de out of memory, et de simplement laisser l'application segfaulter. (Mais que l'application soie conçue pour ne pas perdre des données en cas de crash, et d'avoir une restauration rapide)

        Dans ce cas, ça va être assez dur d'utiliser la biblitohèque standard, boost ou Qt, comme tu lui suggères

        Je suggère de ne pas créé sois même de classe/fonction template.

        • [^] # Re: Oublies le C.

          Posté par (page perso) . Évalué à 3.

          C'est un autre sujet, mais, en fonction du type d'application, je conseil de ne pas geré de cas de out of memory, et de simplement laisser l'application segfaulter.

          Surtout que ça peut ne pas être aussi simple que de tester le retour à NULL/0 suivant la plateforme. Par exemple, Linux envoie un pointeur non nulle même si la mémoire demandée n'est pas disponible, mais les choses peuvent se gâter plus tard lorsqu'on souhaite écrire dedans et que le noyau ne peut toujours pas avoir la mémoire requise.

          • [^] # Re: Oublies le C.

            Posté par . Évalué à 3.

            Sur ce cas précis, le comportement du noyau est réglable via /proc/sys/vm/overcommit_memory

            • [^] # Re: Oublies le C.

              Posté par (page perso) . Évalué à 1.

              Oui m'enfin tu ne vas pas dire à tous les utilisateur de ton appli d'aller modifier ce paramètre du noyau eux-même…

        • [^] # Re: Oublies le C.

          Posté par (page perso) . Évalué à 2.

          Sinon il y avait aussi:

          Un faucille est plus « simple et cohérente » qu'une moissonne batteuse. Mais je préfère utiliser une moissonneuse batteuse.

          Mais c'est déjà assez sympa de ne pas avoir fait appel à la traditionnelle voiture.

          Si tu veux des détails, il suffit de demander.

          Tu peux initialiser les variables non objet avec la syntaxe du constructeur, comme dans:

          int a (5);

          À part pousser les gens à croire qu'un int est un objet, à quoi sert cette syntaxe?

          Le C++ est plein de mécanismes complexes qui n'intéragissent pas très bien entre eux, par exemple
          la surcharge d'opérateur qui ne se combine pas super bien avec les namespaces.

          Ensuite le C++ propose beaucoup de mécanismes analogues avec quelques petites différences subtiles:
          il faut donc souvent faire des choix d'architecture, et c'est difficile les choix, surtout pour les débutants. Par exemple, on peut très bien utiliser un struct à la place d'un namespace la plupart du temps. Les particularités sont que le struct peut être argument d'un template et pas le namespace, tandis que le namespace peut-être déclaré par petits bouts et pas le struct.

          Le C a ses propres défauts (qui ont presque tout été gardés en C++) mais le C++ est bien pire.

          Sinon si tu veux des arguments supplémentaires sur les 1001 incohérences du C++ tu peux regarder là

          http://yosefk.com/c++fqa/index.html

          • [^] # Re: Oublies le C.

            Posté par (page perso) . Évalué à 3.

            par exemple la surcharge d'opérateur qui ne se combine pas super bien avec les namespaces.

            Tu peux élaborer ?

            Mais en général, il est vrai que le C++ a plein de petits défauts, le C aussi. Mais rien qui ne rebute un bon programmeur, comparé au plaisir d'utiliser les possibilité offerte par le C++

            • [^] # Re: Oublies le C.

              Posté par (page perso) . Évalué à 3.

              par exemple la surcharge d'opérateur qui ne se combine pas super bien avec les namespaces.

              Tu peux élaborer ?

              On prend l'exemple suivant

              namespace a {
                class Example {};
              }

              Je veux écrire un opérateur << pour mon Example. Laquelle de ces déclarations est la bonne?

              namespace a
              {
                std::ostream& operator<<(std::ostream& os, const Example& x);
              }

              ou bien

              namespace std
              {
                ostream& operator<<(ostream& os, const a::Example& x);
              }

              ou encore

              std::ostream& operator<<(std::ostream& os, const a::Example& x);

              Si tu mets plus de 5 minutes à répondre à la question ou que tu utilises un compilateur, j'ai gagné, okay?

              • [^] # Re: Oublies le C.

                Posté par (page perso) . Évalué à 5.

                C'est pas la deuxième réponse car on ne peux pas ajouter des trucs dans le namespace std.
                D'est donc la première ou la dernière réponse. Je dirais que les deux sont correcte. Je préfère la première si Example et operator<< sont dans la même partie du code.
                J'ai bon?

        • [^] # Re: Oublies le C.

          Posté par (page perso) . Évalué à 5.

          Un boulier compteur est plus « simple et cohérent » qu'une calculatrice électronique. Mais je préfère utiliser une calculatrice.

          En fait il n'a quand même pas tort, la simplicité et l'élégance du C sont très appréciables (ce qui lui confèrent aussi des difficultés supplémentaires).
          Tu peux voir à peu près l'ensemble des mécanisme du C en quelques mois d'apprentissage et maitriser le langage après quelques années de pratiques bien intensifs. Le C++ est tellement vaste qu'une vie entière rend ceci impossible (le concepteur du langage lui même le dit) et si tu ajoutes l'apprentissage des bibliothèques comme Boost ou Qt, tu es obligé de faire un choix dans le sous-ensemble que tu souhaites apprendre du C++.
          La réalisation de compilateur complet pour le C est du coup aussi beaucoup plus simple ce qui l'a rendu très attractif pour les systèmes embarqués (le C++ y arrive de plus en plus mais souvent avec un support partiel uniquement).

          C'est un autre sujet, mais, en fonction du type d'application, je conseil de ne pas geré de cas de out of memory, et de simplement laisser l'application segfaulter. (Mais que l'application soie conçue pour ne pas perdre des données en cas de crash, et d'avoir une restauration rapide)

          Tu as raison en partie sur ce point.
          Il est clair que si l'allocation d'un objet de quelques octets échoue, c'est que ta machine est à la ramasse partout car elle n'a de mémoire nulle part et doit swapper à mort depuis un moment. Que l'application crash à ce moment (sans destruction de données bien entendu) est un traitement d'erreur qu'on pourrait considérer comme acceptable car après tout à part quitter tu n'as pas grand chose à faire.

          Si par contre l'objet est plus conséquent il peut être intéressant de fermer le tout proprement voire d'essayer de revenir à un état stable précédent. C'est par exemple ce que font les SGBD en général.

          • [^] # Re: Oublies le C.

            Posté par (page perso) . Évalué à 3.

            Il est clair que si l'allocation d'un objet de quelques octets échoue, c'est que ta machine est à la ramasse partout car elle n'a de mémoire nulle part et doit swapper à mort depuis un moment. Que l'application crash à ce moment (sans destruction de données bien entendu) est un traitement d'erreur qu'on pourrait considérer comme acceptable car après tout à part quitter tu n'as pas grand chose à faire.

            Ça dépend complètement de l'application! Si tu fais du calcul numérique en C++ tu as intérêt à gérer correctement l'épuisement de la mémoire disponible pour ton processeur. Ce type d'application favorise grandement la fragmentation de la mémoire et alloue de gros objets: le système peut très bien tourner sainement et quand-même refuser une alloc trop grosse.

            Dans un domaine différent on peut mettre des quotas sur les processus, ça peut aussi être une raison pour lesquelles la demande de mémoire échoue, sans que le système ne soit particulièrement sous pression.

            • [^] # Re: Oublies le C.

              Posté par (page perso) . Évalué à 3.

              Ça dépend complètement de l'application

              Je suis entièrement d'accord.

              le système peut très bien tourner sainement et quand-même refuser une alloc trop grosse.

              C'est ce que je dis, si l'allocation d'un gros objet échoue tu peux fermer proprement ou revenir à un état stable, suivant l'importance de l'application et de l'allocation en question. Cela est plus délicat quand l'allocation est petite (mais là encore, totu dépend du contexte).

              Dans un domaine différent on peut mettre des quotas sur les processus, ça peut aussi être une raison pour lesquelles la demande de mémoire échoue, sans que le système ne soit particulièrement sous pression.

              Dans ce cas c'est ton application qui n'a plus de mémoire et tu trouves un problème : tu ne peux plus avancer avec ton programme. Bien sûr ça dépend des cas, il se peut que l'allocation petite soit mineure et qu'on s'en passe et qu'il n'y a pas besoin de mémoire supplémentaire. C'est à voir, je voulais surtout dire qu'un échec d'allocation ne devait pas systématiquement être traité proprement car c'est inutile. Mais c'est au programmeur d'analyser le cas et de sortir la procédure adaptée.

          • [^] # Re: Oublies le C.

            Posté par . Évalué à 2.

            la simplicité et l'élégance du C […]

            Vraiment ? Le C simple et élégant ? Honnêtement, si t'amuses à faire de la POO en C, ça va être sacrément moche (rien que la syntaxe pour les pointeurs de fonction, mmh, ravissant et pas du tout error-prone). Tu me diras qu'on peut aussi éviter la POO (bah oui, c'est bien connu la POO c'est qu'une mode/ça a été inventé par les SSII pour faire du fric), mais je suis pas sur que ça t'amène à du code vraiment plus élégant. De manière plus générale, un langage avec des pointeurs et des mallocs, c'est un langage de bas niveau, et c'est rarement ce qui permet d'exprimer les algorithmes de manière élégante. On y gagne en performance par contre.

            Quand au troll sur le fait qu'il faut une vie entière pour apprendre le C++, je ne sais même pas quoi répondre. C'est complètement exagéré. Certes c'est un langage compliqué, y'a des pièges un peu partout, mais enfin, on est quand même plusieurs milliers sur cette planète à l'utiliser pour faire des logiciels, c'est donc que c'est faisable.

            • [^] # Re: Oublies le C.

              Posté par (page perso) . Évalué à 4.

              Vraiment ? Le C simple et élégant ? Honnêtement, si t'amuses à faire de la POO en C,

              J'ai dit que le C utilisé tel qu'il a été conçu (donc pas pour faire la POO) c'est simple et élégant.
              je ne parle pas des bricolages pour transformer le C en un langage qu'il n'est pas à la base.

              me diras qu'on peut aussi éviter la POO (bah oui, c'est bien connu la POO c'est qu'une mode/ça a été inventé par les SSII pour faire du fric

              La POO est une bonne chose mais il n'y a pas que ça dans la vie pour programmer proprement.

              Quand au troll sur le fait qu'il faut une vie entière pour apprendre le C++, je ne sais même pas quoi répondre. C'est complètement exagéré. Certes c'est un langage compliqué, y'a des pièges un peu partout, mais enfin, on est quand même plusieurs milliers sur cette planète à l'utiliser pour faire des logiciels, c'est donc que c'est faisable.

              Tu n'as pas compris ce que je voulais dire par là.
              On parle de maitriser le langage de font en comble. Quand tu développes un logiciel tu maitrises rarement le langage et encore moins l'entièreté.
              On estime qu'un expert C nécessite un bon paquets d'années d'expérience pour y parvenir à ce stade. Le C++ est bien plus vaste et avec bien plus de possibilités. Cela rend le langage riche et puissant mais très tortueux (surtout que sa conception est étrange) et rallonge la durée d'apprentissage.

              C'est le créateur du langage lui même qui le dit, je pense qu'il est bien placé pour l'affirmer.

              • [^] # Re: Oublies le C.

                Posté par . Évalué à 2.

                On estime qu'un expert C nécessite un bon paquets d'années d'expérience pour y parvenir à ce stade. Le C++ est bien plus vaste et avec bien plus de possibilités. Cela rend le langage riche et puissant mais très tortueux (surtout que sa conception est étrange) et rallonge la durée d'apprentissage.

                Bon, on est déjà descendu d'un cran (une vie entière -> durée d'apprentissage allongée). Je ne vais pas te contredire sur le fait que C++ est vaste et compliqué.

                Honnêtement, a-t-on vraiment besoin de maîtriser un langage de fond en comble ? Ce qui compte c'est de le connaître suffisamment bien pour l'utiliser pour développer (ce qui nécessite tout de même de le maîtriser hein) et c'est totalement faisable pour du C++ (et oui, en quelques années, on peut largement devenir un bon, voir un très bon programmeur C++, à moins d'avoir le cerveau en ciment).

                • [^] # Re: Oublies le C.

                  Posté par (page perso) . Évalué à 1.

                  On parle de maitrise complète de tous les sous-ensembles du langage afin d'en avoir un contrôle absolu.
                  Oui on peut devenir programmeur C++ très correct en quelques années, je parle d'un niveau supérieur qui est atteignable en C car sa légèreté font qu'il est possible de le maitriser entièrement.

                  Du coup en C++ tu vas sans doute te spécialiser dans certains domaines du langage au détriment d'autres… Cela ne te rend pas incompétent pour autant, je ne dirais jamais ça.

    • [^] # Re: Oublies le C.

      Posté par . Évalué à 4.

      Il est aujourd'hui ridicule de choisir le C face au C++.

      Chaque langage a ses forces et ses faiblesses. Pour une tâche donnée, certains langages seront mieux adaptés que d'autres. Le fait qu'un langage soit "multi-paradigmes" ne suffit pas à le qualifier comme langage idéal pour tous les besoins. Python aussi est multi paradigmes (et j'aime beaucoup le python), c'est par pour ça que je vais en mettre partout.

      La citation pertinente :

      Quand ton seul outil est un marteau, tout ressemble à un clou

      et la trollesque :

      quand ton marteau est c++, tout ressemble à un doigt

      Ca fait pas avancer le débat, mais c'est aussi constructif que ta première phrase (plus constructif même, parce qu'il y a un marteau dedans ;-) )

      • [^] # Re: Oublies le C.

        Posté par (page perso) . Évalué à 2.

        Chaque langage a ses forces et ses faiblesses. Pour une tâche donnée, certains langages seront mieux adaptés que d'autres.

        Entièrement d'accord. Et ce que je dis c'est que le C est dans quasi tout les cas moins bien adapté que le C++.
        (Ok, quand on programme pour un microcontrôleur avec quelques K de mémoire pour lequel il n'y a pas de compilateur C++ disponible, alors le C est plus adapté. Mais pour le reste?)

        • [^] # Re: Oublies le C.

          Posté par . Évalué à 3.

          En mettant de côté le fait que je n'aime pas le C++, je vois d'autres contextes ou choisir le C par rapport au C++ à du sens:
          - une base de code existe déjà en C pour le projet,
          - on a besoin de portabilité,
          - une librairie dynamique (les problèmes de mangling en C++, c'est super pénible),
          - une librairie qui sera bindée dans plusieurs language de plus haut niveau (Java, C++, Python, …),
          - surement d'autres si je me creusais la tête plus longtemps.

          Les 3 derniers relèvent un peu du même contexte : besoin d'intégration avec d'autres trucs que du C++

          • [^] # Re: Oublies le C.

            Posté par (page perso) . Évalué à 0.

            • une base de code existe déjà en C pour le projet,

            Ok. C'est un bon point. Mais pas quand on commence un nouveau projet.

            • on a besoin de portabilité,

            Quel genre de portabilité ? C++ est très portable.

            une librairie dynamique (les problèmes de mangling en C++, c'est super pénible),

            En quoi c'est pénible ? Il y a des bibliothèques qui font la conversion des noms de symboles pour toi.

            • une librairie qui sera bindée dans plusieurs language de plus haut niveau (Java, C++, Python, …),

            Déjà tu peux toujours utiliser extern "C" pour exporter une interface plus « simple ».
            Ensuite, Python et Java étant des langage objets eux aussi, c'est plus facile de mapper le concept d'objet d'un langage vers l'autre en C++ qu'en C. Dans tous les cas tu dois faire un effort pour faire des bindings. (Passage du type string d'un langage vers char* ou vers std::string c'est le même travail. Mais pour le second, la gestion de la mémoire est claire.)

            • [^] # Re: Oublies le C.

              Posté par . Évalué à 6.

              Quel genre de portabilité ? C++ est très portable.

              ça dépend. Si tu n'utilises toujours le même compilo sur toutes les plate formes, ça ira. Par contre, si tu utilises le compilo de Sun sur Solaris, le compilo d'HP sur HP-UX, g++ sur Linux, etc … il vaut mieux ne pas utiliser les fonctionnalités trop récentes, parce qu'elles risquent de n'être supportées que par g++.

              En quoi c'est pénible ? Il y a des bibliothèques qui font la conversion des noms de symboles pour toi.

              je ne parlais pas de l'interprétation des symboles manglés pour qu'ils soient lisibles par un humain (nm -C !!) mais des problèmes d'intégration au runtime.
              Le mangling n'étant pas standardisé, chaque compilo utilise le sien propre. Il n'est pas imaginable de linker deux libs binaires produites par deux compilos différents. Si tu compiles tout toi même, pas de problème. Par contre, si tu link sur des libraires externes, en plus de la version de la lib, tu dois gérer un paramètre de dépendance supplémentaire. Eventuellement, si tu récupères une lib binaire dont tu n'as pas les sources, tu te retrouves contraint à l'utilisation du compilateur qui a servi à générer cette lib.
              Pire, deux versions différentes d'une même suite de compilation peuvent être incompatibles entre elles (c'est le cas de g++, qui pète régulièrement la compatibilité du mangling).
              Côté mise en prod, ça peut aussi être un joyeux boxon. Pour peu que l'infrastructure technique ne soient pas complètement bien contrôlée, et que plusieurs services interviennent …

              tu peux toujours utiliser extern "C" pour exporter une interface plus « simple ».

              oui, tu peux (en fait t'as pas le choix), mais c'est particulièrement pas objet, et ça tire son lot de contrainte. Tu ne peux pas exposer n'importe quoi via des extern "C", et ça peut demander parfois pas mal de contorsions pour arriver à un truc qui marche.

              Ensuite, Python et Java étant des langage objets eux aussi, c'est plus facile de mapper le concept d'objet d'un langage vers l'autre en C++ qu'en C.

              Alors là, je demande à voir. Tu vas faire du extern "C" de toute façon.

              • [^] # Re: Oublies le C.

                Posté par (page perso) . Évalué à 3.

                il vaut mieux ne pas utiliser les fonctionnalités trop récentes, parce qu'elles risquent de n'être supportées que par g++.

                Pareil pour C.

                Le mangling n'étant pas standardisé, chaque compilo utilise le sien propre.

                Il existe un standard (Itanium C++ ABI) qui est respecté par GCC et par clang.
                On peux parfaitement lier des binaires clang et GCC ensemble.

                Par ailleur, le C n'a pas d'ABI standard non plus. (Les conventions d'appel de fonction en C sont aussi différente en fonction du compilo)

                Il n'est pas imaginable de linker deux libs binaires produites par deux compilos différents.

                Pas de problème pour lier des libs compilé avec clang et GCC.

                Pire, deux versions différentes d'une même suite de compilation peuvent être incompatibles entre elles (c'est le cas de g++, qui pète régulièrement la compatibilité du mangling).

                Il ne l'ont plus cassé depuis qu'ils utiliser l'ABI Itanium pour GCC 3.2 en 2002. J'apelle pas ça régulier.

                Alors là, je demande à voir. Tu vas faire du extern "C" de toute façon.

                Non je ne vais pas utiliser extern "C" de toute façon, je disait que c'était possible.
                Pour voir, regarde les bindings python de Qt par exemple.

          • [^] # Re: Oublies le C.

            Posté par (page perso) . Évalué à 4. Dernière modification le 01/10/13 à 00:02.

            Les 3 derniers relèvent un peu du même contexte : besoin d'intégration avec d'autres trucs que du C++

            Il y a un truc que tu as loupé dans ta liste c'est la sécurité. En 2003 quelqu'un a commité une backdoor dans le noyau Linux:

            http://marc.info/?l=linux-kernel&m=106807279904947&w=1

            En C++, entre la spécialisation de templates, la surcharge d'opérateurs, les références et les namespaces, un individu mal intentionné a un attirail de bien meilleur qualité pour brouiller les pistes. C'est beaucoup plus facile de relire du code C que du code C++.

            • [^] # Re: Oublies le C.

              Posté par (page perso) . Évalué à 2.

              Je ne pense pas. Il est déjà possible de cacher plein de truc avec des macros ou autre, je ne pense pas que le C++ sois moins facile à relire que du C.
              Une surcharge ou un operator douteux est la même chose qu'une macro douteuse.

              • [^] # Re: Oublies le C.

                Posté par (page perso) . Évalué à 1.

                Je ne pense pas. Il est déjà possible de cacher plein de truc avec des macros ou autre,

                C'est quoi «ou autre»? Tu jettes tous les éléments de ma liste sauf un, ajoute du vent, et tu conclues «c'est pareil». Si ce n'est pas de l'argumentation de qualitay, ça!

                • [^] # Re: Oublies le C.

                  Posté par (page perso) . Évalué à 3.

                  Cacher des truc dans des macros, utiliser = à la place de ==, utiliser une mauvaise arithmétique de pointeur pour modifier un autre membre dans une structure, mettre ??/ à la fin d'un commentaire d'une ligne. Bref, tout les trucs classique d'obscuration du code.

                  La surcharge d'opérateur c'est pas bien méchant. Il n'y a pas de différence entre ces deux codes:

                  mystruct3 = mystruct1 + mystruct2

                  et

                  mystruct3 = mystruct_add(mystruct1, mystruct2);

                  Appart le fait que l'un est plus lisible, tu peux quand même mettre n'importe quoi dans chacune des fonction donc tu dois savoir ce qu'elle font. En général un bon IDE te met un tooltip par dessus l'opérateur et te permet de sauter directement à son implémentation.

                  Et quand tu implémente un opérateur qui ne fait pas ce qu'il est sensé faire, c'est louche. Il faut avoir de vachement bonne raison pour surcharger l' operator,

                  Pour l'overloading ou les spécialisation de template, je ne vois pas comment tu peux cacher quoi que ce soit.

                  Et pour les référence, c'est vrai qu'il faut faire attention à la signature des fonctions. Là encore un bon IDE aide. Quand on respecte des convention sensée dans un programme ce n'est pas du tout un problème.

                  Bref, je ne penses pas que le C++ aide à cacher des backdoor. Le C lui même est déjà suffisent. Et de bonnes pratiques de programmation aident dans les deux cas.

                  • [^] # Re: Oublies le C.

                    Posté par (page perso) . Évalué à 2.

                    Appart le fait que l'un est plus lisible, tu peux quand même mettre n'importe quoi dans chacune des fonction donc tu dois savoir ce qu'elle font. En général un bon IDE te met un tooltip par dessus l'opérateur et te permet de sauter directement à son implémentation.

                    Voilà, donc en C tu peux relire un patch mais pas en C++ puisque tu as besoin de ton IDE pour savoir ce qui se passe. Donc contrôler les commits dans un projet en C++ est plus difficile qu'en C, en particulier pour la sécurité.

                    (Plus difficile ça ne veut pas dire infaisable.)

        • [^] # Re: Oublies le C.

          Posté par . Évalué à 4.

          En fait tu dis que chaque langage à ses forces et ses faiblesses, et que la faiblesse du C++, c'est que si c'est impossible pour une plateforme donnée de le choisir, dans ce cas on peut à la rigueur prendre le C, mais sinon jamais car il faut toujours choisir le C++.

          Et sinon le week-end, tu sonnes chez les gens pour leur parler du C++ et de la fin du monde, et leur refourguer le bouquin de Stroustru p?

  • # Fais-le...

    Posté par . Évalué à 10.

    … en Java!

    Je n'ai aucune idée de l'intérêt technique à le faire en Java.
    Par contre, avec Java:
    -ça fera super-pro devant les clients qui n'y connaissent rien, parce qu'ils ont tous entendu parler de Java, c'est un truc de pro
    -si c'est lent et bogué, tout le monde trouvera ça normal, c'est pas l'essentiel: l'essentiel c'est que c'est modulaire, souple, et autres adjectifs inutiles/sans aucun sens dans le contexte
    -tu pourras enjoliver ton CV avec des superlatifs java-esques!

    [C'était la minute inutile de Maclag, vous pouvez reprendre une discussion constructive]

  • # Evite le C++

    Posté par . Évalué à 1.

    La reponse depend de toi. Si tu connais bien le C++ ou si c'est un projet a valeur educative, alors prend le C++. Si tu ne connais pas bien le C++ et si tu tiens a avoir un resultat utilisable et maintainable… Evite a tout pris le C++ ! Je rajouterais meme, si tu dois travailler en equipe et que cette equipe n'est pas tres tres stable dans le temps (genre tout le monde reste au moins 2 ans sur le projet).

    Les abus de ce language sont tel qu'elles ouvrent la porte a plein d'horreur dans lesquel tombe les debutants qui rendent impossible la maintenance d'un projet en C++. En gros faut eviter comme la peste toutes les surcharges d'operateur, les passages par reference et autre subtilite qui cache de l'information. Si tu ne fais pas ca, accroche toi pour debugger et optimiser ton projet.

    J'ai vu tellement de projet en entreprise echoue sur cet ecueil que je pense que le C++ est trop complique pour la majorite des developpeurs et des projets. Le seul cas ou ca marche, c'est quand tu as une equipe competente, dedie et volontaire…

    • [^] # Re: Evite le C++

      Posté par . Évalué à 1.

      J'ai du mal aussi avec les références je trouve les pointeurs 1000 fois plus simple. On sait ce qu'on fait au moins

      • [^] # Re: Evite le C++

        Posté par (page perso) . Évalué à 4.

        Bof, une référence c'est un pointeur implicite et tu es sûr qu'il n'est pas NULL.

        Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

        • [^] # Re: Evite le C++

          Posté par (page perso) . Évalué à 2.

          et tu es sûr qu'il n'est pas NULL.

          Tu veux dire comme dans

          int &ma_ref = *mon_int_ptr;
          

          c'est ça?

          • [^] # Re: Evite le C++

            Posté par (page perso) . Évalué à 3.

            Sauf que là tu as dû jouer avec un… pointeur, qui permet en effet de bidouiller en C++, comme en C vu que tu manipules directement l'adresse.

            Je penses plus à des cas comme:

            void mafonction(MaStructure& param);

            Et plus loin une utilisation par référence:
            ```C++
            {
            MaStructure s;

            mafonction(s);
            }
            ```

            Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

            • [^] # Re: Evite le C++

              Posté par (page perso) . Évalué à 3.

              Et ta fonction mafonction n'est jamais appelée avec un pointeur nul déréférencé en argument. Un exemple du genre

              MaStructure* macopie = monargument->clone();
              mafonction(*macopie);

              est bien-sûr complètement artificiel et n'arrive jamais dans du vrai code.

              Sauf que là tu as dû jouer avec un… pointeur, qui permet en effet de bidouiller en C++, comme en C vu que tu manipules directement l'adresse.

              Désolé mais les pointeurs font partie du langage C++ ce qui veut en particulier dire qu'il existe des fonctions qui renvoient des pointeurs. (Pour la bonne raison que les références n'ont pas de sémantique de propriété mais seulement d'alias.) Donc qu'on passe des arguments de type référence avec comme valeur des pointeurs déréferencés — qui peuvent bien-sûr être nul.

              La vraie différence entre une référence et un pointeur est qu'une référence ne peut pas être deleted.

    • [^] # Re: Evite le C++

      Posté par . Évalué à 3.

      Disclaimer : je ne nie pas les apports du C++ au monde du développement, mais c'est un langage que je n'aime pas (pour tout un tas de raisons).

      Le C++ n'est pas du "C avec des syntaxes en plus pour faire de l'objet". L'approche "je migre en C++ en n'utilisant que l'héritage" me parait super casse gueule. Très probablement, à un moment, va se présenter un problème qui nécessitera de rentrer plus profondément dans le langage (et pleurer ?! :) ).

      j'ajoute deux liens :

      • tout l'article est passionnant, mais j'en extrait ce qui est peut-être le plus pertinent pour un débutant en C++:

      C++ has become an extremely complex language. There are countless ways of doing the same thing — almost all of them either plain wrong, dangerous, unmaintainable, or all of the above. The problem is that most code compiles and even runs.

      et même, soyons fou, je propose une traduction :

      C++ est devenu un langage extrêmement complexe. Il y a d'innombrables façons de faire une même chose — presque toutes sont complètement fausses, ou dangereuses, ou non maintenables, voire les trois en même temps. Le problème, c'est que la plupart du code compile, et même s'exécute.

      • un article de Rob Pike (co-créateur de Go) se demandant pourquoi il n'y a pas plus de développeurs C++ qui s'intéressent à Go. tl; dr: il y a trop de fonctionnalités dans C++
      • [^] # Re: Evite le C++

        Posté par (page perso) . Évalué à 2.

        Le premier article est en effet un très bonne critique du C++.
        Note que les article compare le C++ par rapport à des langage de haut niveau. Pas avec le C.
        Des argument tel que « Le C++ c'est trop difficile à apprendre » sont un peu légés. Particulièrement vis à vis du C. (Ça demande plus d'apprentissage d'écrire une lettre avec un ordinateur et tous ces virus, tous ces menus, et crashes. Ça ne veux pas dire qu'il faut conseiller une machine à écrire mécanique car c'est plus simple à première vue)

        presque toutes sont complètement fausses, ou dangereuses, ou non maintenables, voire les trois en même temps.

        Pareil pour le C. Faire des cast de type à tout bout de champ par exemple.

        • [^] # Re: Evite le C++

          Posté par . Évalué à 2.

          Le C++ c'est trop difficile à apprendre

          "Le C++ est difficile à apprendre" n'est pas un bon argument. Par contre, "le C++ est trop difficile à apprendre", ça se discute. Pour le reformuler, la question est de savoir si le temps que tu vas investir à maîtriser les subtilités du C++ va payer. C'est impossible à mesurer à priori, on ne peut que s'appuyer sur son intuition et ce qu'on peut lire sur le sujet. Si j'avais du faire autre chose que du C il y a 10 ans, j'aurais sûrement fait du C++. Mais aujourd'hui, avec la pléthore de langage qui bénéficie de l'expérience du C++, et notamment des endroits ou le langage s'est un peu fourvoyé, j'aurais pas du tout envie de rentrer dans la complexité C++ (Avis personnel, chacun en pense ce qu'il veut).

          Pareil pour le C.

          pas tout à fait. Même en écrivant du C++ "non-C" (pas de gestion de mémoire manuelle, utilisation des exceptions et tout ce qu'il faut), il y a plus de fonctionnalités dans C++, et la combinatoire pour mal les utiliser est plus élevée.

          Faire des cast de type à tout bout de champ par exemple.

          je veux bien un exemple de code avec ce que tu considères être des "cast à tout bout de champs", parce que ça ne me parait pas être une fatalité.

          Je ne dis pas que le C est supérieur au C++ (ça serait crétin). Il est indéniable que le C++ permet, pour ceux qui le maîtrisent, de développer beaucoup plus vite qu'en C. Il y a même des situations ou du code en C++ tourne plus vite que du C. Mais le C++ est un langage exigeant. La migration du C au C++ n'est pas indolore, voire coûteuse. Faut voir si ça vaut le coup ou pas. Je ne dis pas autre chose (même s'il m'a fallu plein de mots pour en arriver là).

          • [^] # Re: Evite le C++

            Posté par (page perso) . Évalué à 3.

            "le C++ est trop difficile à apprendre", ça se discute.

            Vu que moins d'un programmeur sur dix est capable d'écrire proprement un opérateur d'affectation entre deux objets (transac-quoi?) on peut dire qu'au moins neuf personnes sur dix qui essaient d'apprendre C++ n'y arrivent pas. Pour moi c'est tout vu, le C++ est trop difficile à apprendre.

            Le pire c'est que, si on ne veut pas se frotter au problème il faut quand-même prendre une mesure active et déclarer private l'opérateur d'égalité — et ne surtout pas l'implémenter!

    • [^] # Re: Evite le C++

      Posté par (page perso) . Évalué à 0.

      Tu dis ça parce que tu ne sait pas coder :-)

      • [^] # Re: Evite le C++

        Posté par . Évalué à 4.

        Je dis ca parce que j'ai vu trop d'horreur !

        • [^] # Re: Evite le C++

          Posté par . Évalué à 2.

          Pourquoi tu n'aimes pas le passage par référence ?

          "La première sécurité est la liberté"

          • [^] # Re: Evite le C++

            Posté par . Évalué à 5.

            Je n'aime pas ce qui fait disparaitre de l'information quand on lit le code. Lorsqu'on passe un objet par reference en C++, on ne le voit que lorsqu'on lit le prototype de la fonction. Cela implique d'avoir un modele mental complet de l'ensemble du code qu'on est entrain de maintenir. Forcement plus la lecture manque d'information, plus les potentiels de bugs sont eleves. C'est au final le meme probleme qu'avec la surcharge d'operateur, on lit le code, mais on ne peut pas voir l'ensemble des appels de fonction et de logique que cela va declencher.

            • [^] # Re: Evite le C++

              Posté par (page perso) . Évalué à 4.

              Cela implique d'avoir un modele mental complet de l'ensemble du code qu'on est entrain de maintenir.

              Wow, rien que ça ?
              C'est un petit peu excessif… dans le doute, il suffit juste de scroller un peu :)
              Franchement, je peux reprocher pas mal de choses au C++, mais je n'ai jamais eu d'effort mental particulier à faire pour savoir si je suis en train de travailler avec une instance ou bien une référence… (sans compter qu'on a finalement très peu d'occasions d'avoir besoin de le savoir)

            • [^] # Re: Evite le C++

              Posté par (page perso) . Évalué à 2.

              Tu n'as pas complètement tort, mais c'est à un moment une question de pragmatisme, savoir définir ce qui a un sens avec un opérateur (ex. une opération entre des valeur matricielles) et ne pas essayer de tout faire rentrer là dedans.

              Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

            • [^] # Re: Evite le C++

              Posté par (page perso) . Évalué à 2.

              C'est au final le meme probleme qu'avec la surcharge d'operateur, on lit le code, mais on ne peut pas voir l'ensemble des appels de fonction et de logique que cela va declencher.

              Tu n'es pas le seul à penser ça! C'est aussi dans les coding style rules de Google.

              http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml

            • [^] # Re: Evite le C++

              Posté par . Évalué à 0.

              Mais tu as réellement besoin de le savoir ? Des langages comme Java ou OCaml passent tout par référence.

              "La première sécurité est la liberté"

              • [^] # Re: Evite le C++

                Posté par . Évalué à 1.

                Des langages comme Java ou OCaml passent tout par référence.

                Non.
                Java passe tout par valeur..
                Pour OCaml, je n’en sais rien par contre.

                • [^] # Re: Evite le C++

                  Posté par . Évalué à 2.

                  L'article raconte à peu prêt n'importe quoi.

                  Le passage par valeur implique une copie dans des registres. Java ne fait pas de copie à chaque appel de méthode sur un objet, et heureusement !

                  L'exemple est stupide :

                  public void foo(Dog d) {
                      d = new Dog("Fifi"); // creating the "Fifi" dog
                  }
                  
                  Dog aDog = new Dog("Max"); // creating the "Max" dog
                  // at this point, aDog points to the "Max" dog
                  foo(aDog);
                  

                  La référence n'étant pas transmise, le comportement est logique. C'est le problème du "pointeur de pointeur" que l'on peut avoir parfois. Si au lieu de créer un nouveau chien, il changeant un champ de son chien, il verrait son erreur.

                  "La première sécurité est la liberté"

                  • [^] # Re: Evite le C++

                    Posté par . Évalué à -1.

                    L'article raconte à peu prêt n'importe quoi.

                    Ha ?
                    Objectivement, j‘ai quand même l’impression que c’est toi qui raconte nawak…

                    Le passage par valeur implique une copie dans des registres.

                    Qu’est ce que les registres viennent foutre dans la définition de pass-by-value.
                    Source ? Ou c’est une définition de derrière les fagots ?

                    Java ne fait pas de copie à chaque appel de méthode sur un objet, et heureusement !
                    si, Java fait une copie : il copie la référence.
                    Il passe la référence par valeur. Il ne passe pas par référence. Nuance…

                    Dans l‘exemple que tu cites, aDog est une référence sur un objet Dog (car Java manipule des références sur les objets, il est ainsi fait).
                    Quand tu appelles la fonction foo, c’est bien une copie de aDog qui est envoyé, pas une référence sur aDog.
                    J‘appelle foo(aDog), la fonction reçoit la valeur (une copie) de aDog => passage par valeur.

                    En revanche en C++, si j’ai une fonction :

                    void foo(Dog& d)
                    

                    Quand je l’appelle

                    Dog aDog;
                    foo(aDog);
                    

                    Je ne passe pas une copie de aDog, mais son adresse.
                    J‘appelle foo(aDog), la fonction reçoit l’adresse de aDog => passage par référence.

                    Que les valeurs que Java passe soit des références sur un truc ne change pas le fait que sémantiquement c’est un passage par valeur, pas un passage par référence comme il existe en C++ par exemple (j’appelle avec A, la fonction reçoit une référence sur A).

                    • [^] # Re: Evite le C++

                      Posté par . Évalué à 2.

                      Cela reste tordu. Dans les fait, tu peux faire une transmission par valeur ou par référence en C++, alors qu'en Java tu ne manipules que des références.

                      "La première sécurité est la liberté"

                      • [^] # Re: Evite le C++

                        Posté par . Évalué à 1.

                        Cela reste tordu.

                        Je suis d‘accord. D’où le fait que cette méprise soit répandue.
                        Je viens de tomber, via Wikipédia, sur un terme qui semblerait plus approprié : call-by-sharing.

                        Dans les fait, tu peux faire une transmission par valeur ou par référence en C++, alors qu'en Java tu ne manipules que des références.

                        Oui, en Java tu n’as pas le choix. Tu ne manipules que des références (sauf types primitifs il me semble), mais au final tout est passé par valeur.

                        • [^] # Re: Evite le C++

                          Posté par . Évalué à 2.

                          "Oui, en Java tu n’as pas le choix. Tu ne manipules que des références (sauf types primitifs il me semble), mais au final tout est passé par valeur."

                          Son explication avec un

                            int foo (plop_t * plop){};
                            ...
                            foo(&plip);
                          

                          est bizarre on peut dire aussi que ce n'est pas plip qui est transmis mais la référence à plip, qui sont donc aussi transmis par valeur.

                          "La première sécurité est la liberté"

                          • [^] # Re: Evite le C++

                            Posté par . Évalué à 1. Dernière modification le 01/10/13 à 14:17.

                            Oui, c’est exact.

                            int foo (plop_t * plop){};
                            ...
                            foo(&plip);
                            

                            Là c’est un pointeur passé par valeur, pas du passage par référence.
                            Le C n’a pas de passage par référence. Mais on peut le simuler via les pointeurs.

                            C’est d‘ailleurs ce que dit l’article Wikipédia

                            The same effect can be emulated in languages like C by passing a pointer (not to be confused with call-by-reference)
                            […]
                            Even among languages that don't exactly support call-by-reference, many, including C and ML, support explicit references (objects that refer to other objects), such as pointers (objects representing the memory addresses of other objects), and these can be used to effect or simulate call-by-reference (but with the complication that a function's caller must explicitly generate the reference to supply as an argument).

                            Mais ça reste une émulation du mécanisme, le résultat est le même que du passage par référence, mais ça reste du passage par valeur.

                            • [^] # Re: Evite le C++

                              Posté par . Évalué à 1.

                              Dans ce cas tu es forcément obligé de passer par valeur car les pointeurs sont un type particulier de valeur (une adresse mémoire).

                              En Java tu passe la référence (adresse) de l'objet, si tu modifie l'objet pointé par la référence il sera modifié dans l'appelant, si tu modifie la référence tu modifie la copie de l'adresse donc dans l'appelant la référence reste la même. Je trouve ça très logique en venant du C. De manière général je n'aime pas ce qui masque des détails dans un code, les références en sont un exemple. En C le même code serait très clair

                              • [^] # Re: Evite le C++

                                Posté par (page perso) . Évalué à 4.

                                Je crois juste que vous vous emmêlez les pinceaux à cause d'un problème de vocabulaire.
                                En java, on parle peut-être de référence mais en réalité, les objets passés aux fonctions sont des pointeurs cachés passés par valeur. Il n'y aucun passage par référence (au sens C++ du terme) en java.
                                Ce qui permet d'avoir un langage moins riche mais moins casse-gueule à la fois.

  • # Le C++

    Posté par (page perso) . Évalué à 6.

    C'est fait pour la POO. Comme disent certains, il peut y avoir des subtilités, il y a des trucs complexes. Mais tu n'es pas obligé d'utiliser toutes les possibilités du langage, les outils de la stl sont tout de même bien pratique - je commence même à utiliser du boost certaines fois (ex. boost.format) - et si tu peux aller vers le C++11, ça en devient un plaisir de faire des boucles sur des conteneurs.

    Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

    • [^] # Re: Le C++

      Posté par . Évalué à 0.

      Déjà je trouve C++ "lourd" mais avec boost je trouve que c'est utiliser un char d'assaut pour tuer une fourmis…

      • [^] # Re: Le C++

        Posté par (page perso) . Évalué à 4.

        C'est ce que je pensais.

        Puis j'ai voulu faire du formatage de chaîne "propre", à la printf mais avec les contrôles de type du C++. Et j'ai un peu changé d'avis sur boost - qui peut être lourd, qui est dans certains cas basé sur des constructions avancées du C++ incompréhensibles pour le développeur C++ moyen, mais qui dans ce cas précis a été tout à fait utilisable.

        etiquette = boost::str(boost::format("cell%d") % numero);

        Et boost comble tout de même un manque de librairies standardisées du C++ dans des domaines comme les synchros multitâche, etc (qui arrivent en partie avec C++11).

        Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

    • [^] # Re: Le C++

      Posté par . Évalué à 3.

      Moi je dirais C++ sans template, sans exception, sans RTTI, en utilisant Qt (c'est VRAIMENT bien).

      Si tu as un peu de temps, que l'occupation mémoire n'est pas un problème, et que le temps de démarrage de l'application n'est pas un soucis, Java peut-être, mais en utilisant Groovy ou Xtend (avec un bon IDE, c'est le pied). Le problème c'est que si tu veux utiliser des choses propres à une plateforme particulière ça ajoute du taffe.

      Perso je garderai le C pour les trucs ou il faut vraiment de grosses perf, où genre ça t'emmerde que this te bouffe un registre. Mais dans ce cas, tu poserais pas la question.

      • [^] # Re: Le C++

        Posté par . Évalué à 3.

        C'est rare les langages qui ne permettent pas un binding vers une fonction C quand les performances sont nécessaires.

        "La première sécurité est la liberté"

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.