Veuillez expliquer pourquoi Java et C donnent des réponses différentes pour ce code

public class Test { public static void main(Ssortingng[] args) { int i = 10; i = i++; System.out.println("value of i is : " + i); } } 

La sortie est: 10

Lorsque j’ai exécuté un code similaire en C , la sortie est 11 .

En ce qui concerne C il s’agit d’ un comportement non défini, car vous essayez de modifier plusieurs fois la même variable dans le même sharepoint séquence sur cette ligne:

 i = i++; 

le projet de norme C99 dans la section 6.5 paragraphe 2, dit:

Entre le sharepoint séquence précédent et le suivant, la valeur stockée d’un object doit être modifiée au plus une fois par l’évaluation d’une expression. De plus, la valeur antérieure doit être lue uniquement pour déterminer la valeur à stocker .

Ceci est bien défini en Java, qui n’a pas le même concept de sharepoint séquence que le C et le JLS (Java Language Specification) s’efforce de garantir la définition de telles opérations. La section 15.7 du JLS dit:

L’ opérande gauche d’un opérateur binary semble être entièrement évalué avant qu’une partie quelconque de l’opérande droit ne soit évaluée. Par exemple, si l’opérande de gauche contient une affectation à une variable et que l’opérande de droite contient une référence à cette même variable, la valeur produite par la référence reflétera le fait que l’affectation a eu lieu en premier. […]

et la section 15.7.2 dit:

Le langage de programmation Java garantit également que chaque opérande d’un opérateur (à l’exception des opérateurs conditionnels &&, || et? 🙂 semble être entièrement évalué avant l’exécution d’une partie de l’opération.

Notez que C ne spécifie pas l’ordre d’évaluation, principalement pour donner au compilateur de meilleures options d’optimisation . Du projet de norme standard section 6.5 paragraphe 3 :

Le groupement des opérateurs et des opérandes est indiqué par la syntaxe.74) Sauf indication contraire ultérieure (pour les opérateurs function-call (), &&, ||,?: Et virgule), l’ordre d’évaluation des sous-expressions et l’ordre dans quels sont les effets secondaires non spécifiés.

Mettre à jour

Si vous souhaitez une discussion sur certaines des différences de philosophie entre Java et le comportement respectif non défini, vous avez le comportement non défini est une décision de conception et le comportement non défini en Java .

C’est un comportement indéfini en C Absence de sharepoint séquence .

En Java, i = i++; post ++ incrémentera la valeur après cette étape. Mais ici, au moment d’atsortingbuer i++ à i , i encore 10 , vous en obtenez 10 . Mais en C, cela peut être différent de Java. Si vous utilisez i=++i en code Java , vous obtiendrez 11.

Java et C sont des langages différents avec des règles différentes. En C, l’ordre exact dans lequel les expressions sont évaluées et les effets secondaires appliqués n’est pas spécifié ; pour une expression telle que i = i++ , rien ne garantit que l’effet secondaire de l’opérateur ++ sera appliqué avant la réalisation de l’affectation. Le résultat variera en fonction de la plate-forme, des parameters d’optimisation et même du code environnant. Le comportement n’est pas défini . le compilateur peut gérer la situation comme bon lui semble, ce qui inclut la génération d’un résultat inattendu.

Java, OTOH, spécifie un ordre d’évaluation ssortingct et que les effets secondaires sont appliqués immédiatement afin que l’expression soit bien définie.