2010-11-22 3 views
7

Oui j'ai lu l'article sur sequence points. Cependant, je ne pouvais pas comprendre pourquoi ++i = 2 invoquerait un comportement indéfini? La valeur finale de i serait 2 indépendamment de quoi que ce soit, alors comment se fait-il que l'expression est ub?Encore une autre question liée aux points de séquence

extrait de code

int main() 
{ 
    int i =0; 
    ++i=2; 
    return 0; 
} 

Désolé mon anglais est pas très bon.

Répondre

9

Vous observer cette valeur sera ce que vous prétendez, c'est ainsi que UB peut se manifester parmi d'autres scénarios possibles. Le programme peut sortir ce que vous attendez, sortir des données non liées, se bloquer, corrompre des données ou dépenser tout votre argent en commandant une pizza. Une fois que la norme C++ indique qu'une construction est UB, vous ne devriez pas vous attendre à un comportement spécifique. Les résultats observés peuvent varier d'un programme à l'autre.

+0

mais comment le résultat peut-il être différent de 2? J'ai essayé sur quelques compilateurs en ligne et hors ligne comprenant gcc, msvC++, intel C++. Je n'ai rien de différent de 2. – AMS

+1

@AMS: Que faire si le programme a également dépensé tout votre argent ou envoyé tous vos mots de passe à un tiers (http://stackoverflow.com/questions/908872/whats-the-worst-example- de-undefined-behavior-real-possible/3554343 # 3554343)? – sharptooth

+0

Et ce n'est pas du tout une blague - je vous encourage à suivre le lien et à lire la réponse. – sharptooth

0

De même lien exact que vous fournissez:

  • En outre, la valeur préalable est accessible uniquement pour déterminer la valeur à stocker.

Qu'est-ce que cela signifie? Cela signifie que si un objet est écrit dans une expression complète, tous les accès et tout à elle au sein de la même expression doit être directement impliqués dans le calcul de la valeur à écrire.

Ici, sur le côté gauche de l'opérateur =, l'accès à i ne participe pas dans le calcul de la valeur écrite.

0

++ i (devrait être) un rvalue, et par conséquent, ne peut pas être utilisé comme lvalue, mais (++ i) = 2; devrait bien fonctionner. Je ne crois pas que ce soit UB, mais, comme toujours, je peux me tromper.

+0

Oui, vous avez tort. L'ajout de parenthèses ne change pas l'analyse de cette expression, l'opérateur de préfixe ++ renvoie un lvalue. L'UB est le résultat de deux écritures dans la même lvalue dans le même point de séquence. –

+0

@Greg Rogers: Merci! –

11

Il semble évident pour vous, parce que de toute évidence i sera premier être affecté i+1, puis secondes être affecté la valeur 2.

Cependant, ces deux missions se produisent dans le même point de séquence, donc il est au compilateur qui se trouve Frist et qui arrive en second lieu, par conséquent différentes implémentations du compilateur peut générer un code qui donnera des résultats différents, il est UB .

+4

Yeap, et aussi le compilateur n'est pas nécessaire de produire le même programme dans différentes compilations. Imprime 0 sur une compilation ane, efface le disque sur un autre. – sharptooth

1

L'appel ++i = 2; n'invoque pas en soi un comportement indéfini; n'importe quel compilateur peut, s'il le veut, faire une action très définie en atteignant ce code. Cependant, la norme C++ stipule qu'une telle opération n'est pas définie, donc un compilateur peut faire quelque chose d'inattendu (comme supprimer tous les fichiers sur le lecteur C ou envoyer un message texte au pape) et être toujours un compilateur compatible. La seule chose qui rend cet UB est que la norme dit que c'est UB.

Peut-être le point le plus important est qu'une version d'un compilateur peut faire quelque chose de différent de la prochaine version du même compilateur.

2

Le comportement non défini se produit parce qu'un compilateur pourrait mettre en œuvre le code suivant:

++i = 2; 

soit comme:

i = 2; 
++i; 

ou

++i; 
i = 2; 

Il est non spécifiée dans la langue, un compilateur pourrait choisir de mettre en œuvre l'un ou l'autre de ce qui précède. Le premier produirait 3 et le second 2. Donc c'est indéfini.