• # Confus

    Posté par  . Évalué à 4 (+3/-1).

    Sous ses airs de clarification, j'ai l'impression que l'article joue d'une certaine confusion / ambiguïté sur des termes mal définis. Tout semble reposer sur la définition du terme "initialize" et si on prend des extraits de l'article, on peut mettre en avant ces mélanges :

    I deliberately didn’t say “the object is initialized on line 2,”

    Line 1 declares an uninitialized object

    Line 2 then assigns an “initial value.” (…) but it’s an assignment, not an initialization (construction).

    Je suis très surpris que la mémoire ne soit pas mentionnée ici, cela aurait permis de clarifier les explications. Dans mon compréhension, il y a deux choses qui sont faites 1. allouer de la mémoire pour une variable 2. écrire une valeur dans cet espace mémoire. A la fin de l'article, j'ai toujours l'impression que le terme "initialiser une variable" peut être interprété de plusieurs façons. C'est sans doute moi qui n'ai pas compris les subtilités évoquées dans cet article.

    • [^] # Re: Confus

      Posté par  (site web personnel) . Évalué à 6 (+3/-0). Dernière modification le 08 août 2024 à 10:08.

      La question est justement dans la distance qui sépare allocation et affectation (initiale dite initialisation ou ultérieure). Dans l'absolu

      • on peut forcer une valeur à l'allocation (genre tous les bits à 0 ou bien à 1 ou …) et dire allocation = initialisation.
      • on peut aussi attendre la prochaine affectation en croisant les doigts (mais il faut que personne d'autre ne vienne lire parce qu'on sait pas trop ce qu'on va y trouver)
      • on peut exploser en exception si quelqu'un regarde.
      • on peut aussi avoir une valeur spéciale this_is_not_what_you_think ou Schrödinger's_cat laissant le choix à la développeuse entre l'exception ou la bravoure/témérité de continuer.
      • on peur attendre la prochaine version du standard pour esquiver la question.
      • [^] # Re: Confus

        Posté par  . Évalué à 3 (+1/-0).

        Si je me trompe pas, ça pose pas mal de problèmes en sécurité (genre variable non initialisée, etc..).

        Et si je me trompe encore moins, les compilos modernes ont tendance à initialiser les variables lors de leur création.

        • [^] # Re: Confus

          Posté par  . Évalué à 3 (+1/-0).

          Oui, et c'est d'ailleurs pou ça que Rust interdit qu'une variable soit déclarée sans être initialisée. Pour Ada, je ne sais pas comment c'est géré.

        • [^] # Re: Confus

          Posté par  . Évalué à 5 (+3/-1).

          Code extrait de l'article du lien

          #include <iostream>
          
          auto f1() {
              char a[] = {'s', 'e', 'c', 'r', 'e', 't', '\0' };
              std::cout << a << "\n";
          }
          
          auto f2() {
              char a[8];
              std::cout << a << "\n";  // today this likely prints "secret"
          }
          
          auto f3() {
              char a[] = {'0', '1', '2', '3', '4', '5', '\0' };
              std::cout << a << "\n";  // overwrites "secret" (if only just)
          }
          
          int main() {
              f1();
              f2();
              f3();
          }

          L'appel à f2() est susceptible de récupérer la mémoire de la pile de l'appel à f1 tel quel … et donc avec les données non effacées, et donc récupérer le secret. Ça n'a pas l'air bon pour la sécurité effectivement.

      • [^] # Re: Confus

        Posté par  . Évalué à 5 (+3/-0).

        Oui mais c'est quelque chose qui me semble trivial dans sa problématique (sauf peut être sur la formulation). Comment résoudre cette problématique est quelque chose d'une toute autre complexité (ce que semble adresser le C++26). Je ne comprends pas en quoi ce sujet pose question, par exemple l'ISO C11 spécifie à propos des objets static :

        All objects with static storage duration shall be initialized (set to their
        initial values) before program startup.

        Et de façon plus globale :

        An initializer specifies the initial value stored in an object.

        Et quelques phrases plus loin :

        If an object that has automatic storage duration is not initialized explicitly, its value is
        indeterminate.

        Le fait que l'objet est une valeur indéterminée avant que sa valeur initiale soit renseignée est connu depuis des années. Donc l'ISO C a répondu a la question en disant que c'est sur la ligne 2 que l'initialisation est faite.

  • # Très intéressante et longue réponse à une question simple

    Posté par  (site web personnel) . Évalué à 5 (+2/-0).

    Très intéressante et longue réponse à une question simple en apparence : c'est détaillé et pédagogique (et étonnant que la problématique se soit maintenue jusqu'au C++26).

    Il aurait pu être intéressant de décliner/préciser la réponse pour les autres types fondamentaux : void, std::nullptr_t, autres entiers (short, long, long long, et les variantes signed/unsigned), flottants (float, double, long double, voire double-double).

Envoyer un commentaire

Suivre le flux des commentaires

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