Partage
  • Partager sur Facebook
  • Partager sur Twitter

Qu'est-ce qu'un destructeur non-trivial ?

    22 février 2024 à 18:28:25

    Salut tout le monde !

    D'après cppreference.com https://en.cppreference.com/w/cpp/language/destructor#Trivial_destructor , un destructeur trivial est un destructeur qui n'effectue aucune action et ne fait, lors de son appel, que désallouer la mémoire utilisée par l'objet.

    Mais dans ce cas, quelle est la différence avec un destructeur non-trivial comme un destructeur vide par exemple ?

    ~MonObjet() {}

    En quoi un destructeur non-trivial est différent ? Est-ce que cette définition insinue qu'un destructeur non-trivial fait donc autre chose en plus de désallouer la mémoire ?

    Merci d'avance ! :pirate:

    -
    Edité par ThomasAirain 22 février 2024 à 18:30:07

    • Partager sur Facebook
    • Partager sur Twitter
      22 février 2024 à 18:46:33

      Un "destructeur vide" EST un destructeur trivial.

      Un destructeur NON-trivial n'est donc pas vide.

      >En quoi un destructeur non-trivial est différent ?

      Bin, comme il est vide, c'est un destructeur trivial, donc 'en quoi" il est différent, bin par définition de ce qu'est un destructeur non-trivial.

      >Est-ce que cette définition insinue qu'un destructeur non-trivial fait donc autre chose en plus de désallouer la mémoire ?

      Oui, comme faire des déconnexions réseaux ou de bases de données, utiliser un pattern de désallocation "non standard", ou même simplement pour désallouer de la mémoire allouée "à la main" et collée dans un pointeur nu bien cracra, etc...

      Si on programme "à l'ancienne", les cas de destructeurs "non-triviaux" se comptent à la pelle.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        22 février 2024 à 19:07:06

        > The destructor is not user-provided

        Dès qu'il y a des accolades, c'est user-provided. Le truc est que du moment où la définition est user-provided dans une unité de traduction, il ne plus plus supposer si en vrai il y a du code ou pas. Et donc, il n'est plus autorisé à optimiser en supposant qu'il ne fait rien.

        Après il pourrait y avoir le cas particulier du inliné vide, mais ... justement ils en ont bien fait un user-provided.

        Démo => https://gcc.godbolt.org/z/jYcoq8oMY

        EDIT-PS: Ce n'est pas le destructeur qui désalloue. C'est indépendant. Pile ou tas, il y aura destruction + restitution de la mémoire de façon implicite, ou explicite (aux éventuelles sur-capsules RAII près qui rendent la chose implicite...)

        -
        Edité par lmghs 22 février 2024 à 19:10:12

        • 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.
          22 février 2024 à 19:16:16

          @bacelar un destructeur vide n'est pas trivial car il est user-provided.

          @lmghs "il n'est plus autorisé à optimiser en supposant qu'il ne fait rien"

          mais du coup c'est quoi cette optimisation dont tu parles ? :pirate:

          • Partager sur Facebook
          • Partager sur Twitter
            22 février 2024 à 19:39:20

            Justement... ne rien faire.

            Si tu passes un objet local (oublions l'élision un instant) par valeur à une fonction, il va y avoir copie. En vrai, un paramètre, coté fonction appelée ce n'est jamais qu'une variable locale. Et donc la fonction quand elle a fini, elle devra restituer/détruire toutes ses variables locales. Et donc appeler (faire un call) du destructeur, aussi vide soit-il. (la libération se fait coté appelant en vrai)

            Regarde le bordel que ça fout: https://gcc.godbolt.org/z/j8WT7c74a (NB: je n'ai pas réussi à empêcher l'inlining du destructeur -- gcc/clang voient qu'il est dans la meme unité de traduction, et ils optimisent à fond)

            EDIT: Ceci est à l'origine d'une critique sur les perf de std::unique_ptr que les compilos ne sont pas autorisés à passer tranquillement en paramètre -- après AMA, ce n'est pas grave, car un unique_ptr ne passe pas son temps à faire des tours de pistes. Il y alloc (cher), il circule un peu de manière pas terrible (mais cout négligeable), et il y a libération (cher à nouveau)

            -
            Edité par lmghs 22 février 2024 à 19:41:53

            • 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.
              22 février 2024 à 20:02:46

              ThomasAirain a écrit:


              Mais dans ce cas, quelle est la différence avec un destructeur non-trivial comme un destructeur vide par exemple ?

              ~MonObjet() {}

              En quoi un destructeur non-trivial est différent ? Est-ce que cette définition insinue qu'un destructeur non-trivial fait donc autre chose en plus de désallouer la mémoire ?

              En complément, il ne faut pas oublier que la destruction n'est pas juste ce qui est dans ce bloc de code, mais également la destruction de la classe de base, la destruction des classes dérivées, la destruction de chaque membre. Il ne faut pas juste que ce destructeur soit vide, mais que toutes les conditions données dans ton lien soient respectées.

              ThomasAirain a écrit:

              mais du coup c'est quoi cette optimisation dont tu parles ? 

              Normalement, un object est créé via son constructeur, libéré via son destructeur, copié via les functions de copie. Et cela pour chaque classe de base, chaque fonction virtuelle, chaque membre de la classe.

              Dans le cas où c'est trivial, cela veut dire que le compilateur peut ne pas appeler ces fonctions une par une, mais faire une initialisation ou une copie directement d'un bloc mémoire, ce qui est beaucoup plus performant. Et pour la destruction, ne rien faire (a part dire au système que la mémoire n'est plus utilisée).

              -
              Edité par gbdivers 22 février 2024 à 20:03:16

              • Partager sur Facebook
              • Partager sur Twitter

              Qu'est-ce qu'un destructeur non-trivial ?

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown