-3

Les opérateurs d'incrémentation/décrémentation de postfix sont-ils évalués après l'évaluation de l'expression ou après l'évaluation de l'ensemble de l'instruction?Évaluation de l'opérateur d'incrémentation de Postfix

#include<stdio.h> 

void main() 
{ 
    int a=0; 
    int b=0; 

    printf("%d %d",a||b,b++); // Output is 1 0 

} 

Mon compilateur évalue les arguments printf de droite à gauche. La réponse de l'expression a || b est 1, cela signifie que b a été incrémenté avant l'évaluation d'un || b (ie b est incrémenté immédiatement après l'évaluation de l'expression b ++)

Je lis ici Incrementing in C++ - When to use x++ or ++x? que postfix incrément/décrément sont évalués après la déclaration entière.

Lequel est correct?

+6

Aucun des deux n'est correct. Le comportement est indéfini.Voir https://stackoverflow.com/questions/949433/why-are-these-constructs-using-undefined-behavior – interjay

+0

Alors cette réponse qui a reçu tant de remises en cause est-elle incorrecte? –

+0

@interjay, En général, quel est le comportement si les variables ne sont pas répétées dans la même instruction? Postfix incrémente-t-il la valeur de la variable après avoir évalué l'expression ou après avoir évalué l'intégralité de l'instruction? –

Répondre

6

L'ordre d'évaluation des arguments de fonction n'est pas spécifié. Tous les effets secondaires liés aux évaluations d'arguments sont appliqués avant que le contrôle ne soit transmis à la fonction appelée.

De la C standard (6.5.2.2 appels de fonction)

10 Il y a un point de séquence après les évaluations de la fonction désignateur et les arguments réels, mais avant l'appel réel.

Voici un programme démonstratif

#include <stdio.h> 

struct 
{ 
    int x; 
} a = { 0 }; 

void f(int x) 
{ 
    printf("x = %d\n", x); 
    printf("a.x = %d\n", a.x); 
} 

int main(void) 
{ 
    f(a.x++); 
} 

Sa sortie est

x = 0 
a.x = 1 

En raison de l'effet secondaire dans cet appel alors un argument dépend d'un effet secondaire d'autre argument et la évaluation de l'effet secondaire séquentiellement indéterminé par rapport aux arguments

printf("%d %d",a||b,b++); 

le programme a un comportement indéfini.

Il existe quatre opérateurs dans C lorsque les effets secondaires sont séquencés entre les évaluations d'opérandes. Ils sont l'opérateur AND logique (& &), l'opérateur OR logique (||) opérateur de virgule (,) et l'opérateur conditionnel (? :).

Par exemple

#include <stdio.h> 

int main(void) 
{ 
    int x = 0; 

    printf("x = %d\n", x++ == 0 ? x : x - 1); 
} 

La sortie du programme est

x = 1 

L'effet secondaire de l'évaluation de l'expression x++ a été séquencée avant l'évaluation de l'expression x après? signe.

+0

"aschepler" (ci-dessous réponse) dit que "En f (x ++) ;, l'incrément se produit avant d'appeler f". Donc, dans votre exemple, l'incrément devrait arriver avant d'appeler f? –

+0

@SagarP L'incrément se produit après l'évaluation de l'argument x ++ (sa valeur est la valeur de l'opérande avant l'incrémentation) et avant que le contrôle soit passé à la fonction appelée avant que le corps de la fonction ne soit exécuté. –

+0

Donc, avant les points de séquence, l'ancienne valeur reste encore et est retournée mais après avoir atteint le point de séquence, la nouvelle valeur incrémentée est disponible qui peut être utilisée par d'autres variables non? –

0

La réponse en haut de la question à laquelle vous avez un lien est inexacte. L'incrément dans x++ est seulement garanti après avoir déterminé la valeur de l'expression, et parfois avant d'évaluer une expression contenant, mais il n'y a pas d'autres garanties sur quand cela arrive.

En particulier, puisque les effets secondaires des arguments sur le même appel de fonction sont séquencés de manière indéterminée, ce programme a un comportement indéfini.

+0

En général, quel est le comportement si les variables ne sont pas répétées dans la même instruction? Postfix incrémente-t-il la valeur de la variable après avoir évalué l'expression ou après avoir évalué l'intégralité de l'instruction? –

+0

@SagarP Cela dépend. Dans 'f (x ++);', l'incrément se produit avant d'appeler 'f'. Dans 'g() + x ++', il n'y a aucune garantie que l'incrément se produise avant ou après l'appel de 'g()' (mais cela ne peut pas arriver pendant). – aschepler

+0

En f (x--), x décrémente-t-il réellement avant d'appeler f? Je me souviens encore que j'ai appelé f (n--) une fois et le code est entré dans la récurrence infinie parce que la valeur de n n'a pas été décrémentée du tout. –