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.
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.
#include<iostream>autof1(){chara[]={'s','e','c','r','e','t','\0'};std::cout<<a<<"\n";}autof2(){chara[8];std::cout<<a<<"\n";// today this likely prints "secret"}autof3(){chara[]={'0','1','2','3','4','5','\0'};std::cout<<a<<"\n";// overwrites "secret" (if only just)}intmain(){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.
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 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).
# Confus
Posté par nico4nicolas . Évalué à 4.
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 :
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 Benoît Sibaud (site web personnel) . Évalué à 6. 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
this_is_not_what_you_think
ouSchrödinger's_cat
laissant le choix à la développeuse entre l'exception ou la bravoure/témérité de continuer.[^] # Re: Confus
Posté par octane . Évalué à 3.
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 totof2000 . Évalué à 3.
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 Thomas Douillard . Évalué à 5.
Code extrait de l'article du lien
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 nico4nicolas . Évalué à 5.
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 :
Et de façon plus globale :
Et quelques phrases plus loin :
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 Benoît Sibaud (site web personnel) . Évalué à 5.
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).
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.