Partage
  • Partager sur Facebook
  • Partager sur Twitter

Questions en C++

Sujet résolu
    30 juillet 2020 à 19:22:07

    Bonsoir, j'aimerais créer cette discussion pour poser diverses questions autour du C++, car même si je trouve des réponses sur Internet, celles-ci sont assez techniques et obscures pour moi (je préviens, c'est assez long).

    1- (même si les pointeurs nus ne devraient pas être utilisés en C++) Faut-il initialiser un pointeur nu à nullptr ou nullptr_t ?

    2- Si std::string est un typedef de std::basic_string, pourquoi ne pas avoir nommé directement la classe string au lieu de basic_string ?

    3- En POO, on conseille de nommer ses objets avec une majuscule (Voiture, Vecteur..) alors que les objets de la STL ne respectent pas cette règle . Est-ce que c'est parce que la règle a été inventée après ou parce qu'on a créé cette règle pour différencier les objets de la STL et ceux du développeur ?

    4- #pragma once est-il supporté par différents compilateurs/OS ?

    5- Faut il utiliser les include guards (ifndef, define, endif) ou #pragma once dans un header ?

    6- Quelles fonctions déclarer inline ?

    7- Pourquoi le compilo décide "réellement" lui-même de mettre une fonction en inline ?

    8- Pourquoi ne pas mettre toutes les fonctions en inline vu que le compilo décide lui-même ?

    9- (Quand) Faut-il créer un constructeur / destructeur par défaut / vide 

    ex : 

    class A {
        public:
            A() {}
    }

    10- Comment expliquer ce bug de tableau C (1/2) ?

    int* a = new int[7];
    std::cout << a[99];    
    // pourquoi ça ne plante pas \
    j'essaie d'afficher le 100e element d'un tableau \
    de 7 elements

    11- Comment expliquer cet autre bug de tableau C (2/2) ?

    int* a = new int[7];
    a[99] = 85;    
    // pourquoi je peux modifier le 100e element \
    d'un tableau à 7 éléments ?
    std::cout << a[99];

    12- Pourquoi le créateur du C++ a créé un nouveau langage au lieu de "simplement" créer une bibliothèque "c++.lib" ?

    Bonne soirée.

    • Partager sur Facebook
    • Partager sur Twitter
      30 juillet 2020 à 20:49:52

      ThomasSayen a écrit:

      1- (même si les pointeurs nus ne devraient pas être utilisés en C++) Faut-il initialiser un pointeur nu à nullptr ou nullptr_t ?

      Pour ce genre de question, tu devrais faire le test toi même. Ca prend 10 secondes a tester sur un IDE en ligne (par exemple https://wandbox.org/ ). Tu comprendras mieux et retiendras mieux en faisant le test par toi même.

      (spoiler : nullptr est une valeur, nullptr_t est un type)

      ThomasSayen a écrit:

      2- Si std::string est un typedef de std::basic_string, pourquoi ne pas avoir nommé directement la classe string au lieu de basic_string ?

      Par que basic_string est utilisé pour générer plusieurs types de classes (wstring, u8string, etc) et cela permet aux utilisateurs de créer leurs propres types de string.

      ThomasSayen a écrit:

      3- En POO, on conseille de nommer ses objets avec une majuscule (Voiture, Vecteur..) alors que les objets de la STL ne respectent pas cette règle . Est-ce que c'est parce que la règle a été inventée après ou parce qu'on a créé cette règle pour différencier les objets de la STL et ceux du développeur ?

      C'est pas une règle. C'est juste certaines libs qui font ca. Et c'est pas le choix que la lib standard et boost ont fait.

      ThomasSayen a écrit:

      4- #pragma once est-il supporté par différents compilateurs/OS ?

      https://en.cppreference.com/w/cpp/preprocessor/impl

      #pragma once is a non-standard pragma that is supported by the vast majority of modern compilers

      ThomasSayen a écrit:

      5- Faut il utiliser les include guards (ifndef, define, endif) ou #pragma once dans un header ?

      Comme tu veux.

      Perso, au niveau pro, je n'ai jamais vu #pragma once.

      ThomasSayen a écrit:

      6- Quelles fonctions déclarer inline ?

      Celle qui ont un intérêt d'être inline. Les petites fonctions en general.

      ThomasSayen a écrit:

      7- Pourquoi le compilo décide "réellement" lui-même de mettre une fonction en inline ?

      Parce que ca lui permet des choix sur ce qui est le plus performant, en utilisant des heuristiques complexes.

      ThomasSayen a écrit:

      8- Pourquoi ne pas mettre toutes les fonctions en inline vu que le compilo décide lui-même ?

      Parce que c'est inutile et lourd. Et que cela ne permet pas de respecter la separation source/header.

      ThomasSayen a écrit:

      9- (Quand) Faut-il créer un constructeur / destructeur par défaut / vide 

      ex : 

      class A {
          public:
              A() {}
      }

      Jamais. Au pire, utilise "= default".

      Le constructeur par défaut n'est pas généré si tu déclares un autre constructeur explicitement. Si tu fais cela mais que tu veux aussi conserver le constructeur par défaut, il faut le déclarer aussi.

      ThomasSayen a écrit:

      10- Comment expliquer ce bug de tableau C (1/2) ?

      int* a = new int[7];
      std::cout << a[99];    
      // pourquoi ça ne plante pas \
      j'essaie d'afficher le 100e element d'un tableau \
      de 7 elements

      N'utilises pas de tableau du C de toute façon.

      Il faut bien comprendre une chose en C et C++ (et probablement d'autres langages), c'est qu'un code qui compile n'est pas forcément un code valide. Le C++ fait confiance aux devs et autorise des codes qui ne semblent pas valides et c'est aux devs de faire gaffe à ce qu'ils font. C'est pour cela que (pour des raisons de performances), il n'y a pas de vérification de l'accès à un tableau.

      C'est que l'on appelle un comportement indéfini (UB = undefined behavior). C'est a dire que cela fait n'importe quoi. Ca peut provoquer rien, une comportement incorrect, un crash, etc. On ne sait pas a l'avance ce qui va se passer quand un code contient un UB.

      ThomasSayen a écrit:

      11- Comment expliquer cet autre bug de tableau C (2/2) ?

      int* a = new int[7];
      a[99] = 85;    
      // pourquoi je peux modifier le 100e element \
      d'un tableau à 7 éléments ?
      std::cout << a[99];

      Idem.

      ThomasSayen a écrit:

      12- Pourquoi le créateur du C++ a créé un nouveau langage au lieu de "simplement" créer une bibliothèque "c++.lib" ?

      Parce que certaines fonctionnalités ne sont pas implémentables dans une lib. Plus précisemebt, tout ce qui est implémentable dans une lib l'est (dans la lib standard, qui est écrite en C++) et ce qui n'est pas implémentable dans une lib est ajouté dans le langage.

      Par exemple, si on veut implementer une classe string, on peut le faire dans la lib standard (ce qui est fait avec std::string), mais le concept meme de "classe" et le mot clé "class" ne peuvent pas être défini dans la lib standard, cela doit etre fait dans le langage.

      -
      Edité par gbdivers 30 juillet 2020 à 20:50:20

      • Partager sur Facebook
      • Partager sur Twitter
        30 juillet 2020 à 21:20:34

        Merci beaucoup pour vos réponses détaillées et claires :). Tant que vous êtes là, j'ai vu sur le forum que vous avez rédigé un cours de C++. Même s'il a été "remplacé" par celui de ZesteDeSavoir, j'aimerais le lire. Où se trouve-t'il ?
        • Partager sur Facebook
        • Partager sur Twitter
          30 juillet 2020 à 21:23:48

          Je n'avais le temps de le mettre a jour donc il n'est plus en ligne.
          • Partager sur Facebook
          • Partager sur Twitter
            30 juillet 2020 à 21:28:45

            D'accord merci pour tout, je met en résolu.
            • Partager sur Facebook
            • Partager sur Twitter
              1 août 2020 à 18:01:18

              3. Il existe beaucoup de conventions, et in fine, ce n'est que ça: une convention. Ici, des gens ont voulu importer des pratiques d'autres langages dans le langage écrit par quelqu'un qui n'utilisait pas cette convention. D'autres langages font le choix de ne pas laisser les développeurs utiliser les conventions qu'il veulent. Le C++ est permissif ici.

              PS: dans le passé, il se faisait pire quand des hordes de développeurs Pascal et autres voulait utiliser C pour des classes, T pour des types, E pour des enums, i des int, o des objets... Bref, un joyeux foutoir qui ne rimait à rien.

              6. Doivent être inline les fonctions que tu tiens (ou dois -> template) absolument définir dans des fichiers d'en-tête qui seront inclus de multiples fois -- Il faut comprendre les chaînes de compilation actuelles (< C++2020) et ce qu'est une unité de traduction pour comprendre pourquoi une fonction définie dans un .h doit absolument être inline.

              Bien souvent, inline (hors cas template), c'est à des fins d'optimisation. Sachant qu'il y a deux aspects; celui dont tout le monde parle où l'appel de fonction est esquivé si le compilateur le désire réellement parce que la fonction est courte. Et il y a celui où le compilateur peut propager les propriétés qu'il connaît sur les paramètres des fonctions pour éliminer des branches à l'intérieur de ces fameuses fonctions.

              Si on part d'une bonne vielle programmation qui dégouline de défensif 

              int f(int * p, int i, int N) {
                  if (!p)     return -1;
                  if (i >= N) return -2;
                  if (i < 0)  return -3;
                  return y(p[i));
              }


              Dans le cas où la fonction est appelée depuis une boucle où il est clair que 0 <= i < N, et avec un pointeur non nul, ET que l'unité de traduction où la boucle est réalisée connaît la définition de cette fonction f(), alors le compilateur sera plus que susceptible de dégager les 3 tests défensifs qui auraient dû être des assertions (ou mieux des contrats, espérons-le en C++23). Dans le cas où la définition de f() n'est pas visible depuis le lieux de son appel, alors, on paiera toujours 3 tests, qui en situation nominale ne devraient jamais rimer à rien.

              Si je ne m'abuse, les travaux autour de la LTO (Link Time Optimisation) devraient permettre cela, mais ça coûte vite cher en temps de link, et de nombreux logiciels sont ainsi compilés sans LTO.

              8. Si tout était inline, avec les modèles de compilation actuels (-> jusqu'au C++17), la moindre modification d'un fichier inclus pourrait induire la recompilation de tout un projet. Quand la compilation from scratch prend plusieurs heures, on préfère éviter.

              Après, il y en a qui tiennent absolument à pouvoir séparer la livraison des interfaces de celles des binaires. Il faut dire que c'est bien utile quand on fournit/récupère des paquets -dev de telle ou telle bibliothèque.

              Il faut voir ce que l'arrivée des modules en C++20 va changer.

              • Partager sur Facebook
              • Partager sur Twitter
              C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                1 août 2020 à 21:44:11

                Merci @lmghs pour votre réponse (j'ai pas tout compris mais je relirai :)).
                • Partager sur Facebook
                • Partager sur Twitter

                Questions en C++

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown