PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > fr.comp.lang.c++ > Comportement indéfini ou pas ?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Comportement indéfini ou pas ?

Réponse
 
LinkBack Outils de la discussion
Vieux 27/02/2008, 17h56   #1
David Côme
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Comportement indéfini ou pas ?

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.
  Réponse avec citation
Vieux 27/02/2008, 18h10   #2
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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.

  Réponse avec citation
Vieux 27/02/2008, 18h29   #3
Anthony Fleury
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 27/02/2008, 19h22   #4
David Côme
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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.
  Réponse avec citation
Vieux 27/02/2008, 19h47   #5
Jean-Marc Bourguet
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 27/02/2008, 22h28   #6
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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.
  Réponse avec citation
Vieux 27/02/2008, 22h37   #7
Gabriel Dos Reis
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 28/02/2008, 01h33   #8
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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.
  Réponse avec citation
Vieux 28/02/2008, 01h33   #9
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind

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.
  Réponse avec citation
Vieux 28/02/2008, 01h38   #10
Gabriel Dos Reis
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind

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
  Réponse avec citation
Vieux 28/02/2008, 05h25   #11
Jean-Marc Bourguet
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 28/02/2008, 08h22   #12
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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

  Réponse avec citation
Vieux 28/02/2008, 08h29   #13
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 28/02/2008, 08h42   #14
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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
  Réponse avec citation
Vieux 28/02/2008, 08h48   #15
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 28/02/2008, 08h58   #16
Jean-Marc Bourguet
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 28/02/2008, 11h07   #17
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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.
  Réponse avec citation
Vieux 28/02/2008, 14h46   #18
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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
  Réponse avec citation
Vieux 28/02/2008, 17h26   #19
Gabriel Dos Reis
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement indéfini ou pas ?

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
  Réponse avec citation
Vieux 28/02/2008, 20h09   #20
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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.
  Réponse avec citation
Vieux 28/02/2008, 21h12   #21
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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
  Réponse avec citation
Vieux 28/02/2008, 21h58   #22
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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.
  Réponse avec citation
Vieux 28/02/2008, 22h08   #23
Sylvain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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.
  Réponse avec citation
Vieux 29/02/2008, 08h50   #24
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Comportement ind??????????????

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