|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Bonjour à tous.
Est ce que ce code à un comportement indéfini ? //iostream est inclue , ... int a; //(1) cout<< a; // (2) Pour ma part: Je pense que la valeur de a est indéfinie car (1) créer une variable sur la pile sans lui affecter de valeur. Elle prend donc la valeur de ce qui se trouvait avant à cette place. Il n'y a pas de moyen de connaitre cette valeur. La valeure de a est indéfini même si certain compilo réalisé une affectation par défaut (je pense à VC++ en mode débug , on peut confirmer ?) Par contre la 2eme ligne, elle a un comportement totalement défini.Elle va afficher la valeur de a, qui peut être n'importe quoi. Suis-je dans le vrai ? Merci. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Wed, 27 Feb 2008 18:56:42 +0100, David Côme <davidcome@wanadoo.fr>:
>int a; //(1) Jusque-là, pas de problème, même si l'utilité d'un tel code m'échappe. >cout<< a; // (2) C'est de toutes façons un comportement indéfini : dans le meilleur des cas, ça affichera un entier, sans qu'il soit possible d'en prévoir la valeur à l'avance. Il me semble que selon la norme, c'est un comportement indéfini tout court (On ne peut pas du tout prévoir le comportement du code) ; toutefois, en pratique, je m'attendrais à ce qu'un entier quelconque soit effectivement affiché. Et il y a même de bonnes chances pour que ce soit le même à chaque exécution, tant qu'on ne recompile pas. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
David Côme a écrit :
> Bonjour à tous. Bonjour, > Est ce que ce code à un comportement indéfini ? > > //iostream est inclue , ... > int a; //(1) > cout<< a; // (2) > > Pour ma part: > Je pense que la valeur de a est indéfinie car (1) créer une variable sur > la pile sans lui affecter de valeur. > Elle prend donc la valeur de ce qui se trouvait avant à cette place. > Il n'y a pas de moyen de connaitre cette valeur. La valeure de a est > indéfini même si certain compilo réalisé une affectation par défaut > (je pense à VC++ en mode débug , on peut confirmer ?) > > Par contre la 2eme ligne, elle a un comportement totalement défini.Elle > va afficher la valeur de a, qui peut être n'importe quoi. > > Suis-je dans le vrai ? Si on considère la plupart des implémentations connues, ça donnera en effet un affichage d'une valeur aléatoire et en effet le comportement peu changer en mode debug selon les compilateurs. Cependant, au regard de la norme, ce code est indéfini car accède à une variable non initialisée (en considérant (1) automatique). Entre autre, a peut très bien contenir une valeur "invalide" pour le système ("trap value") qui ferait remarquer au-dit système que la variable utilisée ne l'est pas d'une manière conforme. Anthony |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Wed, 27 Feb 2008 19:10:55 +0100, Fabien LE LEZ <gramster@gramster.com>
wrote: > On Wed, 27 Feb 2008 18:56:42 +0100, David Côme <davidcome@wanadoo.fr>: > >> int a; //(1) > > Jusque-lÃ, pas de problème, même si l'utilité d'un tel code m'échappe. > Ce code n'a pas d'utilité propre. C'est juste pour illustre l'utilisation d'une variable non initialisée. >> cout<< a; // (2) > > C'est de toutes façons un comportement indéfini : dans le meilleur des > cas, ça affichera un entier, sans qu'il soit possible d'en prévoir la > valeur à l'avance. > Normal. > Il me semble que selon la norme, c'est un comportement indéfini tout > court (On ne peut pas du tout prévoir le comportement du code) ; Je ne savais pas. > toutefois, en pratique, je m'attendrais à ce qu'un entier quelconque > soit effectivement affiché. Et il y a même de bonnes chances pour que > ce soit le même à chaque exécution, tant qu'on ne recompile pas. > Comme moi. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Fabien LE LEZ <gramster@gramster.com> writes:
> On Wed, 27 Feb 2008 18:56:42 +0100, David Côme <davidcome@wanadoo.fr>: > > >int a; //(1) > > Jusque-là, pas de problème, même si l'utilité d'un tel code m'échappe. > > >cout<< a; // (2) > > C'est de toutes façons un comportement indéfini : dans le meilleur des > cas, ça affichera un entier, sans qu'il soit possible d'en prévoir la > valeur à l'avance. > > Il me semble que selon la norme, c'est un comportement indéfini tout > court (On ne peut pas du tout prévoir le comportement du code) ; J'ai pas vérifié, mais c'est ce que je pense. En particulier, ça peut être une valeur déclanchant une exception (trois cas plausibles: la représentation de ce qui serait -0 sur une machine en complément à 1 ou grandeur et signe qui n'admet pas de -0; mauvais tags sur une machine où les valeurs ont un tag; il y a eu une machine n'ayant que des nombres en virgule flottante, mais où certaines opérations trappaient si une donnée n'était pas entière). > toutefois, en pratique, je m'attendrais à ce qu'un entier quelconque soit > effectivement affiché. Sur les machines courantes, c'est le comportement le plus vraissemblable. > Et il y a même de bonnes chances pour que ce soit le même à chaque > exécution, tant qu'on ne recompile pas. Ca dépend de ce que tu appelles exécution. Ca ne m'étonnerait pas trop que ceci void f(int i) { int k = i; } void g() { int a; std::cout << a << std::endl; } int main() { f(42); g(); f(36); g(); } affiche 42 puis 36. Et ca dépend aussi du système, tous ne remettent pas toute la mémoire à 0 entre processus (c'est certainement une mauvaise idée de ne pas le faire sur des machines à usage général). A+ -- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/...ite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Anthony Fleury wrote on 27/02/2008 19:29:
> >> Est ce que ce code à un comportement indéfini ? >> >> //iostream est inclue , ... >> int a; //(1) >> cout<< a; // (2) >> > Entre autre, a peut très bien contenir une valeur "invalide" pour le > système ("trap value") qui ferait remarquer au-dit système que la > variable utilisée ne l'est pas d'une manière conforme. j'ai du mal à saisir la finesse de l'indéfinition. je ne vois ici qu'une imprévision (non connaissance d'une valeur aléatoire, ou comment se paraphraser). surtout je ne vois pas ce que serait un *int* "invalide" !! vous avez des machines sur lesquelles un int, disons 32 bits, peut contenir toutes les valuers entières entre 0x00000000 et 0xFFFFFFFF *plus* d'autres valeurs invalides ??? Sylvain. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Sylvain <noSpam@mail.net> writes:
| Anthony Fleury wrote on 27/02/2008 19:29: | > | >> Est ce que ce code à un comportement indéfini ? | >> | >> //iostream est inclue , ... | >> int a; //(1) | >> cout<< a; // (2) | >> | > Entre autre, a peut très bien contenir une valeur "invalide" pour le | > système ("trap value") qui ferait remarquer au-dit système que la | > variable utilisée ne l'est pas d'une manière conforme. | | j'ai du mal à saisir la finesse de l'indéfinition. | je ne vois ici qu'une imprévision (non connaissance d'une valeur | aléatoire, ou comment se paraphraser). | | surtout je ne vois pas ce que serait un *int* "invalide" !! | vous avez des machines sur lesquelles un int, disons 32 bits, peut | contenir toutes les valuers entières entre 0x00000000 et 0xFFFFFFFF | *plus* d'autres valeurs invalides ??? So ? -- Gaby |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Gabriel Dos Reis wrote on 27/02/2008 23:37:
> | > | surtout je ne vois pas ce que serait un *int* "invalide" !! > | vous avez des machines sur lesquelles un int, disons 32 bits, peut > | contenir toutes les valuers entières entre 0x00000000 et 0xFFFFFFFF > | *plus* d'autres valeurs invalides ??? > > So ? so, vous avez des machines sur lesquelles un int, disons 32 bits, peut contenir toutes les valuers entières entre 0x0 et 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides ??? la hiérarchie fr. utilise ISO-8859-1 pas UTF-8. Sylvain. |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Gabriel Dos Reis wrote on 27/02/2008 23:37:
> | > | surtout je ne vois pas ce que serait un *int* "invalide" !! > | vous avez des machines sur lesquelles un int, disons 32 bits, peut > | contenir toutes les valuers entières entre 0x00000000 et 0xFFFFFFFF > | *plus* d'autres valeurs invalides ??? > > So ? so, vous avez des machines sur lesquelles un int, disons 32 bits, peut contenir toutes les valuers entières entre 0x0 et 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides ??? la hiérarchie fr. utilise ISO-8859-1 pas UTF-8. Sylvain. |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
Sylvain <noSpam@mail.net> writes:
| Gabriel Dos Reis wrote on 27/02/2008 23:37: | > | | surtout je ne vois pas ce que serait un *int* "invalide" !! | > | vous avez des machines sur lesquelles un int, disons 32 bits, peut | > | contenir toutes les valuers entières entre 0x00000000 et 0xFFFFFFFF | > | *plus* d'autres valeurs invalides ??? | > So ? | | so, vous avez des machines sur lesquelles un int, disons 32 bits, | peut contenir toutes les valuers entières entre 0x0 et 0xFFFFFFFF | *plus* d'autres valeurs, accessoirement invalides ??? et donc ? -- Gaby |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Sylvain <noSpam@mail.net> writes:
> surtout je ne vois pas ce que serait un *int* "invalide" !! J'ai donné 3 cas de machines ayant existés où la non initialisation pourrait fournir un int invalide. Je ne sais pas s'il y a eu des implémentations de C++ pour ces machines, mais le C++ est conçu pour y permettre une implémentation sans lui imposer d'initialiser toutes les variables. On peut aussi parfaitement imaginer une implémentation qui vérifierait dynamiquement la non utilisation de variables non intialisées. Une autre source de problèmes, même avec des machines où toutes les représentations sont valides, ce sont les optimisations. A partir du moment où le comportement est formellement indéfini, le compilateur peut supposer qu'il n'arrive pas et laisser ses algorithmes d'optimisation se comporter n'importe comment si l'hypothèse n'est pas vraie. N'importe comment, ca peut avoir des effets non causals, ou inconsitants. int x; //0 for (i = 0; i < 10; ++i) { if (f(i)) x = g(i); } std::cout << x << std::endl; //1 int y; for (i = 0; i < 10; ++i) { if (h(i)) { y = p(i); x = q(i); } } std::cout << x << " " << y << std::endl; //2 peut parfaitement afficher deux fois des valeurs différentes pour x même si f(i) et h(i) ne retourne jamais true. Raisonnement pas hors de portée des techniques d'optimisation actuelles: x est non initialisé en 0, utilisé en 1 donc on assigne une valeur entre les deux. même raisonnement pour y entre 1 et 2. Mais si y est assigné entre 1 et 2, x l'est aussi, donc x a deux utilisations distinctes (entre 0 et 1 et entre 1 et 2) et donc la valeur de x ne doit pas être conservée après 1, pour diminuer la pression sur l'allocateur de registre, on introduit une variable en plus pour ce deuxième intervalle. L'allocateur fait son boulot et assigne des registres différents à x pour x entre 0 et 1 et entre 1 et 2. Résultat, deux valeurs différentes pour x sont affichées. A+ -- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/...ite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
On Feb 27, 7:10 pm, Fabien LE LEZ <grams...@gramster.com> wrote:
> On Wed, 27 Feb 2008 18:56:42 +0100, David Côme <davidc...@wanadoo.fr>: > >int a; //(1) > Jusque-là, pas de problème, même si l'utilité d'un tel code > m'échappe. On peut vouloir le faire si la valeur d'initialization dépend d'un bloc de code, avec par exemple des if. Mais ce n'est pas courant, et même dans ce cas-ci, je préfèrerais l'initialiser avec quelque chose (peut-être 0), simplement pour que le code soit déterministe, même dans le cas d'erreur plus tard qui fait qu'on ne l'initialise pas. > >cout<< a; // (2) > C'est de toutes façons un comportement indéfini : dans le > meilleur des cas, ça affichera un entier, sans qu'il soit > possible d'en prévoir la valeur à l'avance. Dans le meilleur des cas, ça provoquera un core dump. Avec la plupart des implémentations, en revanche, ça affichera une valeur numérique non-spécifiée (dans le langage de la norme, c-à-d même pas garantie d'être la même deux fois de suite). > Il me semble que selon la norme, c'est un comportement > indéfini tout court (On ne peut pas du tout prévoir le > comportement du code) ; toutefois, en pratique, je > m'attendrais à ce qu'un entier quelconque soit effectivement > affiché. Et il y a même de bonnes chances pour que ce soit le > même à chaque exécution, tant qu'on ne recompile pas. Dans les cas simple, oui. Si par exemple ça, dans le main(), c'est tout son programme. Dans les cas plus compliqué, je n'y compterais pas -- si ce bout de code se trouve dans une fonction, et qu'on a appelé d'autres fonctions avant, ce qu'il affiche dependrait de ce qu'ont fait ces autres fonctions, d'une façon assez imprévisible. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
On Feb 27, 8:47 pm, Jean-Marc Bourguet <j...@bourguet.org> wrote:
> Fabien LE LEZ <grams...@gramster.com> writes: > > On Wed, 27 Feb 2008 18:56:42 +0100, David Côme > > <davidc...@wanadoo.fr>: > > >int a; //(1) > > Jusque-là, pas de problème, même si l'utilité d'un tel code > > m'échappe. > > >cout<< a; // (2) > > C'est de toutes façons un comportement indéfini : dans le > > meilleur des cas, ça affichera un entier, sans qu'il soit > > possible d'en prévoir la valeur à l'avance. > > Il me semble que selon la norme, c'est un comportement > > indéfini tout court (On ne peut pas du tout prévoir le > > comportement du code) ; > J'ai pas vérifié, mais c'est ce que je pense. En particulier, > ça peut être une valeur déclanchant une exception (trois cas > plausibles: la représentation de ce qui serait -0 sur une > machine en complément à 1 ou grandeur et signe qui n'admet pas > de -0; mauvais tags sur une machine où les valeurs ont un tag; > il y a eu une machine n'ayant que des nombres en virgule > flottante, mais où certaines opérations trappaient si une > donnée n'était pas entière). Une autre possibilité (qui existe réelement) : l'implémentation traque les accès, maintient un bit map de ce qui est initialisé, et ce qui ne l'est pas, et vérifie à chaque accès. (Purify le fait, par exemple, et le code ci-dessus génèrerait une sortie d'erreur de la part de Purify.) [...] > Et ca dépend aussi du système, tous ne remettent pas toute la > mémoire à 0 entre processus (c'est certainement une mauvaise > idée de ne pas le faire sur des machines à usage général). À 0, je ne sais pas, mais une machine à usage général est bien obligé d'y écrire quelque chose, pour des raisons de sécurité. (La mémoire qui est affectée à mon processus aurait bien pû appartenir à un processus à toi avant, et en contenir des données confidentielles.) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
On Feb 28, 2:33 am, Sylvain <noS...@mail.net> wrote:
> Gabriel Dos Reis wrote on 27/02/2008 23:37: > > > surtout je ne vois pas ce que serait un *int* "invalide" > > > !! vous avez des machines sur lesquelles un int, disons > > > 32 bits, peut contenir toutes les valuers entières entre > > > 0x00000000 et 0xFFFFFFFF *plus* d'autres valeurs invalides > > > ??? > > So ? > so, vous avez des machines sur lesquelles un int, disons 32 > bits, peut contenir toutes les valuers entières entre 0x0 et > 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides > ??? C'est tout à fait concevable, et il a même existé des systèmes où la mémoire a des bits de parité. Invisible au programme, mais initialisés uniquement à la première écriture. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
On Feb 28, 6:25 am, Jean-Marc Bourguet <j...@bourguet.org> wrote:
> Sylvain <noS...@mail.net> writes: > On peut aussi > parfaitement imaginer une implémentation qui vérifierait > dynamiquement la non utilisation de variables non intialisées. Pas besoin de l'imaginer. Chez la plupart de mes clients, on interdisait le déployement du code sans qu'il ait tourné sur un tel système (Purify, en l'occurance). (Je me rappelle le problème que ça a causé quand on voulait écrire sur disque une struct avec un char[n] initializé avec strcpy(). Purify râlait bien qu'on écrivait des octets qui n'avaient pas été initialisés.) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> writes:
> On Feb 28, 6:25 am, Jean-Marc Bourguet <j...@bourguet.org> wrote: > > Sylvain <noS...@mail.net> writes: > > > On peut aussi > > parfaitement imaginer une implémentation qui vérifierait > > dynamiquement la non utilisation de variables non intialisées. > > Pas besoin de l'imaginer. Chez la plupart de mes clients, on > interdisait le déployement du code sans qu'il ait tourné sur un > tel système (Purify, en l'occurance). (Je me rappelle le > problème que ça a causé quand on voulait écrire sur disque une > struct avec un char[n] initializé avec strcpy(). Purify râlait > bien qu'on écrivait des octets qui n'avaient pas été > initialisés.) Purify fait un peu trop pour qu'on puisse le considerer comme part de l'implementation (je l'ai deja vu raler sur du code genere par le compilateur sans que rien dans le source ne pose probleme par exemple), mais je l'avais en tete quand j'ai ecrit cela. A+ -- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/...ite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
James Kanze wrote on 28/02/2008 09:42:
> >> so, vous avez des machines sur lesquelles un int, disons 32 >> bits, peut contenir toutes les valuers entières entre 0x0 et >> 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides >> ??? > > C'est tout à fait concevable, et il a même existé des systèmes > où la mémoire a des bits de parité. Invisible au programme, mais > initialisés uniquement à la première écriture. la mémoire avec parité ou encore ECC existe toujours. ses états sont invisibles du code utilisateur comme de toute librairie standard, y compris celle de cout. même dans ce cas je n'arrive pas à imaginer une valeur spéciale faisant traper l'injecteur. Sylvain. |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
On Feb 28, 12:07 pm, Sylvain <noS...@mail.net> wrote:
> James Kanze wrote on 28/02/2008 09:42: > >> so, vous avez des machines sur lesquelles un int, disons 32 > >> bits, peut contenir toutes les valuers entières entre 0x0 et > >> 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides > >> ??? > > C'est tout à fait concevable, et il a même existé des systèmes > > où la mémoire a des bits de parité. Invisible au programme, mais > > initialisés uniquement à la première écriture. > la mémoire avec parité ou encore ECC existe toujours. ses > états sont invisibles du code utilisateur comme de toute > librairie standard, y compris celle de cout. Certes, mais il n'est pas forcement bien initialisé à la mise sous tension. Alors, si tu lis une valeur à une adresse qui n'a jamais été écrite, tu risques bien un plantage. > même dans ce cas je n'arrive pas à imaginer une valeur > spéciale faisant traper l'injecteur. Qu'est-ce qui se passe s'il y a une erreur de parité, alors ? (Tu peux imaginer ce que tu veux, j'ai déjà travaillé sur de tels systèmes. En C, en tout cas.) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> writes:
| On Feb 28, 6:25 am, Jean-Marc Bourguet <j...@bourguet.org> wrote: | > Sylvain <noS...@mail.net> writes: | | > On peut aussi | > parfaitement imaginer une implémentation qui vérifierait | > dynamiquement la non utilisation de variables non intialisées. | | Pas besoin de l'imaginer. Chez la plupart de mes clients, on | interdisait le déployement du code sans qu'il ait tourné sur un | tel système (Purify, en l'occurance). (Je me rappelle le | problème que ça a causé quand on voulait écrire sur disque une | struct avec un char[n] initializé avec strcpy(). Purify râlait | bien qu'on écrivait des octets qui n'avaient pas été | initialisés.) Ou, le compilateur peut lui meme generer des instructions de trap. -- Gaby |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
James Kanze wrote on 28/02/2008 15:46:
> On Feb 28, 12:07 pm, Sylvain <noS...@mail.net> wrote: >> James Kanze wrote on 28/02/2008 09:42: > >>>> so, vous avez des machines sur lesquelles un int, disons 32 >>>> bits, peut contenir toutes les valuers entières entre 0x0 et >>>> 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides >>>> ??? > >>> C'est tout à fait concevable, et il a même existé des systèmes >>> où la mémoire a des bits de parité. Invisible au programme, mais >>> initialisés uniquement à la première écriture. > >> la mémoire avec parité ou encore ECC existe toujours. ses >> états sont invisibles du code utilisateur comme de toute >> librairie standard, y compris celle de cout. > > Certes, mais il n'est pas forcement bien initialisé à la mise > sous tension. Alors, si tu lis une valeur à une adresse qui n'a > jamais été écrite, tu risques bien un plantage. ah bon ?! il y a de la mémoire avec bit de parité (1 bit) ou avec correction d'erreur (n bits) qui fait exprès de contenir des valeurs d'erreurs - ou plutôt il existe des cartes dont le controleur mémoire fait expres de générer n'importe quoi ... je ne savais pas. j'aurais même penser qu'une telle situation ne pouvait pas durer plus de quelques nanosecondes (temps de "refresh" moyen), à moins que la mémoire "qui n'a jamais été écrite" ne soit pas rafraichie... >> même dans ce cas je n'arrive pas à imaginer une valeur >> spéciale faisant traper l'injecteur. > > Qu'est-ce qui se passe s'il y a une erreur de parité, alors ? en ECC ? le controleur l'a déjà corrigé. avec bit de parité simple, ça dépends du BIOS, mais cela ne regarde nullement le code - avec variables non initialisées - chargé; lorsqu'il est chargé, tous ces octets ont une parité correcte ou le système (le hard!) était déjà défaillant. > (Tu peux imaginer ce que tu veux, j'ai déjà travaillé sur de > tels systèmes. En C, en tout cas.) fort bien, "et donc" (c)(r)(tm) ? Sylvain. |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
On Feb 28, 9:09 pm, Sylvain <noS...@mail.net> wrote:
> James Kanze wrote on 28/02/2008 15:46: > > On Feb 28, 12:07 pm, Sylvain <noS...@mail.net> wrote: > >> James Kanze wrote on 28/02/2008 09:42: > >>>> so, vous avez des machines sur lesquelles un int, disons 32 > >>>> bits, peut contenir toutes les valuers entières entre 0x0 et > >>>> 0xFFFFFFFF *plus* d'autres valeurs, accessoirement invalides > >>>> ??? > >>> C'est tout à fait concevable, et il a même existé des systèmes > >>> où la mémoire a des bits de parité. Invisible au programme, mais > >>> initialisés uniquement à la première écriture. > >> la mémoire avec parité ou encore ECC existe toujours. ses > >> états sont invisibles du code utilisateur comme de toute > >> librairie standard, y compris celle de cout. > > Certes, mais il n'est pas forcement bien initialisé à la mise > > sous tension. Alors, si tu lis une valeur à une adresse qui n'a > > jamais été écrite, tu risques bien un plantage. > ah bon ?! il y a de la mémoire avec bit de parité (1 bit) ou avec > correction d'erreur (n bits) qui fait exprès de contenir des valeurs > d'erreurs - ou plutôt il existe des cartes dont le controleur mémoire > fait expres de générer n'importe quoi ... je ne savais pas. À la mise sous tension, la mémoire contient effectivement n'importe quoi. (Aussi, la plupart des contrôleurs dont je me suis servi dans le temps prévoyaient bien une commande pour écrire des valeurs erronées. Pour des motifs de test, si rien d'autre. Mais le problème réel, c'est que jusqu'à la première écriture, le contenu n'est pas défini, et il y a des chances qu'il soit invalid.) > j'aurais même penser qu'une telle situation ne pouvait pas > durer plus de quelques nanosecondes (temps de "refresh" > moyen), à moins que la mémoire "qui n'a jamais été écrite" ne > soit pas rafraichie... Dans le cas où je l'ai rencontré, il s'agissait des mémoires statiques, sans refraiche. Mais je conçois bien aussi des cas où des mémoires dynamiques ne font pas jouer la détection d'erreurs lors des cycles de refraiche. > >> même dans ce cas je n'arrive pas à imaginer une valeur > >> spéciale faisant traper l'injecteur. > > Qu'est-ce qui se passe s'il y a une erreur de parité, alors ? > en ECC ? le controleur l'a déjà corrigé. Il ne peut pas en corriger toutes les erreurs possibles. Que des erreurs d'un seul bit, et certaines de deux bits. > avec bit de parité simple, ça dépends du BIOS, mais cela ne > regarde nullement le code - avec variables non initialisées - > chargé; lorsqu'il est chargé, tous ces octets ont une parité > correcte ou le système (le hard!) était déjà défaillant. Tu parles comme si on chargeait la mémoire à partir d'un disque. (Dans un système classique, évidemment, il n'y a pas de chances que ça se produisent, parce que le système écrit toute la mémoire avant de te la donner.) Moi, j'ai rencontré le problème dans des systèmes embarqués, avec le programme en PROM, et pas de disque. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
James Kanze wrote on 28/02/2008 22:12:
> > À la mise sous tension, la mémoire contient effectivement > n'importe quoi. (Aussi, la plupart des contrôleurs dont je me > suis servi dans le temps prévoyaient bien une commande pour > écrire des valeurs erronées. Pour des motifs de test, si rien > d'autre. Mais le problème réel, c'est que jusqu'à la première > écriture, le contenu n'est pas défini, et il y a des chances > qu'il soit invalid.) certes mais ce n'est pas le cas décrit ici. évidemment toute la mémoire n'est pas vérifié à chaque tic d'horloge (lorsqu'elle est rafraichie), elle l'est uniquement lorsqu'elle est lue, or pour que le code: "int x; cout << x;" soit lu en mémoire et fourni au CPU, il faut qu'il ait été écrit dans cette mémoire, lors de cette écriture la valeur int32 (pas 33, ni 36, ni autre) non initialisée (en supposant que le compilo n'est pas utilisé un registre) est écrite en mémoire et son CRC est correctement calculé. >> j'aurais même penser qu'une telle situation ne pouvait pas >> durer plus de quelques nanosecondes (temps de "refresh" >> moyen), à moins que la mémoire "qui n'a jamais été écrite" ne >> soit pas rafraichie... > > Dans le cas où je l'ai rencontré, il s'agissait des mémoires > statiques, sans refraiche. Mais je conçois bien aussi des cas où > des mémoires dynamiques ne font pas jouer la détection d'erreurs > lors des cycles de refraiche. yep, à la lecture uniquement. >>>> même dans ce cas je n'arrive pas à imaginer une valeur >>>> spéciale faisant traper l'injecteur. > >>> Qu'est-ce qui se passe s'il y a une erreur de parité, alors ? > >> en ECC ? le controleur l'a déjà corrigé. > > Il ne peut pas en corriger toutes les erreurs possibles. Que des > erreurs d'un seul bit, et certaines de deux bits. en effet, mais ici encore l'amalgame est erroné. le chargement de la valeur non prédictible a copié tels-quels tous les bits et a calculé le ou les bits de contrôle, si une particule cosmique vient basculer un ou 2 bits, le CRC le(s) corrigera. il n'a pas à corriger "toutes les valeurs possibles" d'une variable non initialisée car cela ne veux strictement rien donne - elle est. elle n'a pas beson de correction, n'étant pas erronée. >> avec bit de parité simple, ça dépends du BIOS, mais cela ne >> regarde nullement le code - avec variables non initialisées - >> chargé; lorsqu'il est chargé, tous ces octets ont une parité >> correcte ou le système (le hard!) était déjà défaillant. > > Tu parles comme si on chargeait la mémoire à partir d'un disque. > (Dans un système classique, évidemment, il n'y a pas de chances > que ça se produisent, parce que le système écrit toute la > mémoire avant de te la donner.) Moi, j'ai rencontré le problème > dans des systèmes embarqués, avec le programme en PROM, et pas > de disque. oui je me plaçais en effet dans ce cas qui me semblait pas trop anecdotique, un contrôleur [E[E]]PROM utilise toujours un contrôle de parité (en premier lieu pour se défendre comme les attaques) mais ici encore il ne détecte que les modifications ayant pu intervenir de manière ciblée (attaque lumière) ou globale (micro-ondes) sur la PROM. il ne se demande pas si un int8 particulier contient tel valeur parce que c'est le bruit du compilo ou parce que le source contenait une valeur intentionelle. en résumé, estimer qu'il peut exister des compilos suffisamment malin pour insérer un trap (une assertion) lorsqu'une variable non initialisée est utilisée - tout en étant assez bête pour ne pas en faire une erreur de compilo - est recevable. (un compilo C51 - embarqué - n'insère pas de tel code). dire qu'une variable n bits non initialisée peut faire traper le système parce qu'elle contient une valeur n+m bits qu'elle ne peut pas contenir est une erreur. Sylvain. |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
Sylvain wrote on 28/02/2008 22:58:
> > il n'a pas à corriger "toutes les valeurs possibles" d'une variable non > initialisée car cela ne veux strictement rien donne - elle est. elle n'a > pas beson de correction, n'étant pas erronée. cela ne veux strictement rien dire - elle est (ce qu'elle est). elle n'a pas besoin de correction, n'étant pas erronée. Sylvain - sans CRC lors de la frappe. |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
On Feb 28, 10:58 pm, Sylvain <noS...@mail.net> wrote: > James Kanze wrote on 28/02/2008 22:12: > > À la mise sous tension, la mémoire contient effectivement > > n'importe quoi. (Aussi, la plupart des contrôleurs dont je me > > suis servi dans le temps prévoyaient bien une commande pour > > écrire des valeurs erronées. Pour des motifs de test, si rien > > d'autre. Mais le problème réel, c'est que jusqu'à la première > > écriture, le contenu n'est pas défini, et il y a des chances > > qu'il soit invalid.) > certes mais ce n'est pas le cas décrit ici. Bien sûr que si. > évidemment toute la mémoire n'est pas vérifié à chaque tic > d'horloge (lorsqu'elle est rafraichie), elle l'est uniquement > lorsqu'elle est lue, or pour que le code: "int x; cout << x;" > soit lu en mémoire et fourni au CPU, il faut qu'il ait été > écrit dans cette mémoire, Où ça ? Certes, il faut que x soit écrit avant d'être lu. Sinon, il y a un comportement indéfini, avec potentiellement un crash du système. Dans le bout du code présenté, et c'était le but de de la question, il n'y a pas eu écriture de x. Il y a donc comportement indéfini, et potentiellement un crash du système CQFD. > lors de cette écriture la valeur int32 (pas 33, ni 36, ni > autre) non initialisée (en supposant que le compilo n'est pas > utilisé un registre) est écrite en mémoire et son CRC est > correctement calculé. Quelle écriture. Justement, dans le cas en question, le mot mémoire où se trouve x n'a jamais été écrit. [...] > le chargement de la valeur non prédictible a copié tels-quels > tous les bits et a calculé le ou les bits de contrôle, si une > particule cosmique vient basculer un ou 2 bits, le CRC le(s) > corrigera. Certes, mais ce dont on parle ici, ce n'est pas un bit qui a changé, suite à n'importe quel aléa, mais la situation où tous les bits du mot ont un contenu aléatoire, suite à la mise sous tension. > il n'a pas à corriger "toutes les valeurs possibles" d'une > variable non initialisée car cela ne veux strictement rien > donne - elle est. elle n'a pas beson de correction, n'étant > pas erronée. Sauf que la valeur leu sera bien erronée. Si on prend le cas d'un mémoire »16 bits«, l'ECC en ajoute 5. À la mise sous tension, ces 21 bits peuvent prendre 2097152 valeurs différent, dont seulement 65536 sont valides. Si tu lis un mot mémoire avant qu'il n'ait été écrit, tu n'as qu'une chance sur 32 que l'ECC dit que c'est valide. Ensuite, l'ECC essaie de corriger -- selon les cas, il y arrive (et tu vois une valeur aléatoire) ou il n'y arrive pas (trop de bits erronés, ou plutôt, une valeur qui ne pourrait se présenter que s'il y avait trop de bits erronés). S'il n'y arrive pas, il provoque l'arrêt du système, ou que sais-je. Dans le cas de parité simple, évidemmen |