2010-10-03 5 views
9
void main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;//is this fine? 
} 

J'ai récemment commencé à lire sur les trucs de points de séquence, mais je ne peux pas savoir si l'exemple de code ci-dessus est bien ou non. Je sais que l'opérateur && introduit un point de séquence donc je ne suis pas très sûr du comportement de l'expression z = x & & y & & ++ z. Quelqu'un s'il vous plaît dites-moi la bonne réponse.expression compliquée impliquant logique ET (&&)

+4

Retour type de 'main()' 'devrait être int' en C et en C++. –

Répondre

-2

Oui, il va compiler.

Mais si vous demandez des bugs logiques:

1) l'opérateur && introduit un point de séquence, car elle pourrait mettre fin à l'évaluation de l'expression quand il sait que le résultat final (dans ce cas, une valeur 0 peut terminer l'évaluation), de sorte qu'il n'atteindra même pas la partie ++z si ou y est zéro. 2) parce que l'opérateur && est logique, le résultat sera toujours 0 ou 1, et je doute que ce soit ce que vous vouliez.

6

En C++ 03.

void main(void) 
{ 
    int x,y,z; 
    x=y=z=1;         // Seq1 at ; 

    z = x && y && ++z;//is this fine?   // Seq2 at ; 
} 

NB: Notez qu'il ya des points de séquence à l'opérateur & & mais ceux qui ne sont pas pertinentes dans cet exemple.

Fine! En général, peut être ou peut être Non. Dépend des valeurs de x et y. Dans votre cas, ce n'est pas bien. Ce code a le potentiel d'avoir quelque chose appelé undefined behavior.

Si z ++ est évaluée (comme dans votre exemple parce que x et y sont 1), alors la variable scalaire « z » est modifié plus d'une fois dans l'expression entre deux séquences points de Seq1 et Seq2 (voir ci-dessous). Il est important de noter que l'opérateur d'affectation n'introduit aucun point de séquence.

5 $/4- « Sauf indication contraire, l'ordre d'évaluation des opérandes de opérateurs individuels et subexpressions individuels expressions, et l'ordre dans lequel effets secondaires ont lieu, est unspecified.53) Entre le précédent et suivant le point de séquence d'un objet scalaire doit avoir sa valeur stockée modifiée au plus une fois par l'évaluation d'une expression. en outre, la valeur préalable est accessible uniquement aux dé terminer la valeur à stocker. Les exigences de ce paragraphe doivent être satisfaites pour chaque sous-expression d'une expression complète pour chaque ordre admissible; sinon le comportement est indéfini. »

En C++ 0x

mettra à jour une fois que je me comprends les détails de la discussion évoquée par @litb.Pour l'instant, je ne fais que le supprimer

En C++ 0X cependant, si je comprends bien, il n'y a pas de concept de points de séquence. Cette expression est correcte et n'invoque pas de comportement indéfini. C'est parce que l'effet de ++ sur 'z' est séquencé avant l'effet secondaire de l'affectation sur 'z'.

1,9/15- $ « Sauf indication contraire, évaluations des opérandes des différents opérateurs et de sous-expressions de expressions individuelles sont non séquencée [Note:. Dans une expression qui est évalué plus d'une fois au cours l'exécution d'un programme, et non séquencée évaluations séquencés pour une période indéterminée de ses sous-expressions ne doit pas être réalisé de manière cohérente dans différentes évaluations. -end ndlr] les calculs de valeur de les opérandes d'un opérateur sont séquencés avant le calcul de la valeur du résultat de l'opérateur. Si un effet secondaire sur un objet scalaire est soit non séquencée par rapport à un autre effet secondaire sur le même objet ou un scalaire calcul de valeur en utilisant la valeur du même objet scalaire, le comportement est indéfini.

$ 3.9/9 - « types Arithmétique (3.9.1), types d'énumération, les types de pointeur, pointeur aux types de membres (3.9.2), std :: nullptr_t et cv-qualifiés versions de ces types (3.9.3) sont collectivement appelés types scalaires. "

Notez que dans l'expression 'z = z ++;' où z est une variable scalaire, les effets secondaires sur 'z' dus à l'opérateur d'affectation et à l'opérateur postfix ++ ne sont pas séquencés (aucun d'entre eux n'est séquencé avant l'autre).

Merci @Prasoon pour donner des contributions précieuses pour affiner ce message de version originale

+2

@Prasoon Saurav: où êtes-vous? – Chubsdad

+2

@ Chubsdad: Le comportement serait indéfini en fonction des valeurs de 'x' et' y'. Mais nous avons 'x = 1' et' y = 1' donc l'évaluation de '++ z' est garantie, donc le comportement serait indéfini car' z' est modifié plus d'une fois entre deux points de séquence [affectation et pré-incrémentation modifiez 'z' deux fois sans aucun point de séquence intermédiaire]. Notez que votre message contient un devis de C++ 0x draft. En C++ 0x 'i = ++ i' est un comportement bien défini. –

+0

Upvoted votre réponse maintenant. :) –

2

Une façon simple de savoir si cette ligne est bien ou non est de laisser le compilateur vérifier. Par exemple, gcc a the -Wsequence-point option (activé par -Wall) pour vérifier s'il y a un comportement indéfini en raison du manque de points de séquence.

Votre programme

int main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;/*is this fine?*/ 

    return 0; 
} 

produit cet avertissement:

 
x.c: In function 'main': 
x.c:6:5: warning: operation on 'z' may be undefined 
+0

Il est frustrant que gcc nécessite une option spéciale pour produire des avertissements à ce sujet au lieu de simplement générer 'movb $ 0,0' ou équivalent pour un tel code. –