En quoi le comportement de cout n'est pas défini? Il va faire autre chose qu'afficher la valeur de a?
Version imprimable
Possible, selon http://www.developpez.net/forums/sho...7&postcount=19
Thierry
comme cité par corrector
sur visual studio 2005 en debug va t'afficher une boite de dialogue. Sous GCC, cela va afficher un truc (personne ne peut vraiment predire quoi).Code:
1
2
3
4
5
6
7
8 #include <iostream> int main() { int a; std::cout << a; return 0; }
Le comportement est donc indefini. CQFD.
Vous pensez que c'est defini car vous pensez que le compilateur va allouer de la place sur la pile, puis que vous allez afficher cette place sur la pile.
Pensez que je pourrais faire un compilateur qui n'alloue pas sur la pile, mais alloue a la demande de la memoire dynamique pour chaque variable. Comme c'est fait sur demande, tant que je ne fais rien je n'alloue pas. Du coup, lorsque je lis cette valeur je n'ai pas encore alloué de l'espace et ca va planter.
lire une valeur non initialisée est indefini, en general ca renvoie une valeur aleatoire (enfin, disons plutot determinée par laposition de saturne et l'age du capitaine, c'est a dire que avec deux executions la valeur sera sans doute identique) mais ce n'est pas la seule implementation possible, et visual studio ajoute une boite de dialogue qui pete a la figure a l'execution.
Il y a des cas où simplement accéder à un pointeur invalide (sans tenter de lire la zone pointée) peut poser un problème. Par exemple, charger un descripteur de segment invalide génère une exception sur un x86.
char peut avoir des trap value... unsigned char non.
Le problème est que la valeur de a n'est pas définie. Et ce qui se trouve par hasard en mémoire peut ne pas être une valeur acceptable. Par exemple il y a eu des machines à tag où chaque mot mémoire avait un tag décrivant son type. Sans initialisation, celui-ci peut être incorrect. Autre exemple, il y a eu une machine qui n'avait comme représentation numérique qu'une représentation flottante mais qui avait des instructions qui trappaient si une valeur n'était pas entière.
Je ne pense pas que ça puisse être compatible avec ceci :
ce qui suggère une contradiction avec la clause de non-initialisation.Citation:
Envoyé par C++ draft N2315, 3.10/15 [basic.lval]
Cette clause est vraiment troublante, car elle suggère de faire des choses que rien n'autorise; en effet, comment obtenir les lvalues suivantes :
alors queCitation:
Envoyé par C++ draft N2315, 3.10/15 [basic.lval]
Dans ce cas, quel intérêt de nous raconter ça :Citation:
Envoyé par C++ draft N2315, 5.2.10/7 [expr.reinterpret.cast]
Encore une phrase qui ne veut rien dire : comment un type signé pourrait avoir la même représentation qu'un type non-signé? En fait, il faut lire quelque chose comme :Citation:
Envoyé par C++ draft N2315, 3.9.1/3 [basic.fundamental]
The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the representation of values in such range shall be the same in both types.
(Zut, moi qui voulais faire une réponse courte.)
Tient, c'est rigolo comme architecture.
Où est-il défini?
Potentiellement, reformater ton disque dur ou démarrer une partie de nethack.
En pratique, c'est vrai qu'il y a moins de risques qu'avec le déréférencement d'un pointeur non initialisé. Mais une variable non initialisée n'est pas juste une variable qui a une valeur inconnue.
Ce n'est pas une enumeration de tous les cas de comportements indefini, mais de comportement qui sont a coup sur indefini. Subtile difference.
Je ne sais pas si ca a change depuis et je n'ai pas le temps de faire une recherche, mais la norme de 98 dit en 3.9.1/1 que char peut etre la meme chose que signed char, et que seul unsigned char est garanti avoir tous les bit patterns comme valeurs acceptables (cas du complement a 1...) meme si on est sur de ne pas avoir de bits ne participant pas a la valeur pour tous les types caracteres.
Si char etait enleve de ta citation, le comportement aurait ete rendu indefini meme dans les implementations pour lesquelles char equivaut a unsigned char. Tel que redige, le comportement est indefini uniquement pour celles ou char equivaut a signed char.
C'est la grosse difficulte de la lecture de la norme, il faut non seulement trouver une description, il faut aussi etre raisonablement sur que ce n'est pas modifie a d'autres endroits.
Pour le reste, j'ai des choses a repondre mais ca attendra que je puisse retrouver les citations adequates.
Formellement, oui. Mais pourquoi spécifier que le comportement est indéfini alors qu'il l'est déjà? (Pourquoi cette clause?)
Pas de changement :
Je n'avais pas vu ça.Citation:
Envoyé par C++ draft N2315, 3.9.1/1
Oula!
Plus précisément : le comportement est indéfini pour les implémentations où CHAR_MAX - CHAR_MIN != UCHAR_MAX. Mais la norme C++ ne parle pas de "trap representation". Formellement, elle ne dit pas explicitement que c'est indéfini.
C'est pas de la tarte!
O___O;
Merci pour les détails!
Une erreur d'attention de ma part (je n'ai pas vu l'ascence d'initialization de i dans l'exemple) aura mis en avant une obscure subtilitée du language :aie: