2010-10-21 6 views
3
#include <iostream> 
using namespace std; 

main(){ 

int i = 5; 

cout << i++ << i--<< ++i << --i << i << endl; 


} 

Le programme ci-dessus compilé avec g ++ donne une sortie:Comportement de l'augmentation de poste Cout

45555 

Alors que le programme suivant:

int x=20,y=35; 

x =y++ + y + x++ + y++; 

cout << x<< endl << y; 

donne le résultat que

126 

37 

Quelqu'un peut-il s'il vous plaît expliquer la sortie.

+1

* « Comportement de l'augmentation de poste prinf » * Vous n'utilisez pas 'printf'. Vous utilisez des flux d'E/S. –

+1

Cela tombe dans la catégorie de qui se soucie. Question stupide demandé un million de fois avant de faire une recherche rapide et vous verrez. Mais même si c'était défini, vous ne le feriez toujours pas dans la vie réelle, encore une fois, qui s'en soucie. –

+3

@Martin: lol ... peut-être ajouter une balise "who-cares" ?? Ce serait amusant. Je pensais ajouter un "pas encore!" tag aussi. –

Répondre

2

comportement non défini, donc tout peut arriver

4

Le résultat de l'expression du second programme est défini. Le compilateur est même autorisé à mettre votre ordinateur en feu :-) Vous n'êtes pas autorisé à modifier une variable deux fois dans un point de séquence (dans ce cas: de = à ;).

Edit:

Pour des explications détaillées, voir the C FAQ, en particulier question 3.2.

+0

* "Vous n'êtes pas autorisé à modifier une variable deux fois dans un point de séquence" * Vous dites que «x = y ++ + y + x ++ + y ++;» n'est pas valide d'une manière ou d'une autre? –

+2

T.J. Crowder> oui. même x = x ++ est invalide. – nothrow

+0

@Yossarian: Oui, je viens de voir le 'x ++' (je pensais qu'il parlait du truc 'y ++'). Surpris, c'est invalide. * Inutile *, mais je suis surpris par "invalide". (BTW: Si vous mettez un '@' au début d'une réponse à un commentaire donnant le nom de l'utilisateur, il leur notifiera qu'ils ont un commentaire, par exemple '@TJ Crowder:' plutôt que 'TJ Crowder> ') –

2

Ajout à d'autres réponses de:

Si vous utilisez g++, en utilisant l'option -Wsequence-point dit que:

$ g++ -Wsequence-point a.cpp 
a.cpp: In function ‘int main()’: 
a.cpp:8: warning: operation on ‘i’ may be undefined 
              ^^^^^^^^^ 
+3

Encore une autre raison d'utiliser les avertissements. Encore un autre. –

9
cout << i++ << i-- 

est sémantiquement équivalent à

operator<<(operator<<(cout, i++), i--); 
      <------arg1--------->, <-arg2-> 

1,9 $/15- "Quand ca le remplissage d'une fonction (si oui ou non la fonction est ligne), chaque calcul de valeur et effet secondaire associé à une expression d'argument , ou avec l'expression postfixe désignant la fonction appelée , est séquencé avant exécution de toutes les expressions ou instruction dans le corps de la fonction appelée. [] Remarque: Les calculs de valeur et les effets secondaires associés à différentes expressions d'argument sont non séquencé. -end noter]

C++ 0x:

Cela signifie que l'évaluation des arguments arg1/arg2 sont non séquencée (aucun d'entre eux est séquencée avant que l'autre).

Le même article dans le projet de norme précise également,

Si un effet secondaire sur un objet scalaire est non séquencée par rapport à soit un autre effet secondaire sur le même objet scalaire ou un calcul de valeur à l'aide de la valeur du même objet scalar, le comportement est indéfini.

Maintenant, il y a un point de séquence à la virgule à la fin de la pleine expression ci-dessous

operator<<(operator<<(cout, i++), i--); 
            ^the interesting sequence point is right here 

Comme il ressort clairement, l'évaluation des deux arg1 et le plomb arg2 à effet secondaire sur la variable scalaire « i », et comme nous l'avons vu ci-dessus, les effets secondaires sont non séquencés.

Par conséquent le code a un comportement indéfini. Alors qu'est-ce que cela signifie?

Voici comment 'comportement indéfini' est défini :) dans la norme.

comportement non défini admissible varie d'ignorer la situation complètement avec des résultats imprévisibles, à se comporter lors de la traduction ou d'un programme exécution d'une manière documentée caractéristique de l'environnement (avec ou sans la délivrance d'un diagnostic message), pour terminer une traduction ou une exécution (avec l'émission d'un message de diagnostic). De nombreuses constructions de programmes erronées n'engendrent pas de comportement indéfini: ; ils doivent être diagnostiqués .

Est-ce que vous voyez la corrélation avec @ réponse de DarkDust « Le compilateur est même autorisé à configurer votre ordinateur :-) incendie »

Ainsi, toute sortie vous obtenez d'un tel code est vraiment dans le domaine tant redouté de comportement indéfini.

Ne le faites pas.

La seule chose qui est defined à propos de ce code est qu'il aide OP et beaucoup d'entre nous obtenir beaucoup de voix (si répondu correctement) :)