2
votes

Comment justifier l'opérateur d'incrémentation de postfix C avec la table de priorité?

Je travaille avec la table de priorité des opérateurs C pour mieux comprendre la priorité des opérateurs de C. J'ai un problème pour comprendre les résultats du code suivant:

int a, b;
a = 1;
b = a++;   // does not seem to follow C operator precedence

Utilisation de la table de priorité de Opérateurs C, je ne peux pas expliquer pourquoi avec l'opérateur postfix ++ , d'abord l'affectation est évaluée puis l'incrémentation.

L'opérateur d'incrémentation postfix ( ++ ) a la priorité la plus élevée en C et l'opérateur d'affectation ( = ) a la priorité la plus basse. Donc, dans le code ci-dessus, le premier postfix ++ doit être exécuté, puis l'affectation = . Par conséquent, les deux variables a et b devraient être égales à 2 mais ce n'est pas le cas.

Pourquoi la priorité de l'opérateur C semble-t-elle ne pas fonctionner avec ce code?

Quand la priorité la plus élevée du suffixe ++ ne s'affiche-t-elle pas?


3 commentaires

Au cas où cela ne serait pas clair, la préséance et l'associativité sont indépendantes de l'ordre d'évaluation. On comprend cependant comment ces termes peuvent être confondus.


a est récupéré pour l'affectation, puis l'emplacement mémoire de a est incrémenté (pas la valeur récupérée).


Je pense que le "post" dans "postfix" indique que l'incrément se produit après tout le reste est évalué. c'est-à-dire char * str = "FreeBSD"; char increment () {((* str ++) + 1)} , le pointeur est dé-référencé, l'arithmétique est appliquée et la valeur renvoyée (dans ce cas, un 'G'.) Ce n'est qu'alors que l'incrémentation appliqué. Cela a été utile lorsque j'ai commencé à me débattre avec des choses comme Duff's Device.


3 Réponses :


5
votes

Cela n'avait rien à voir avec la préséance. Il s'agit de savoir comment fonctionne l'opérateur postfix ++ .

L'opérateur postfix ++ évalue à la valeur courante de son opérande, et a pour effet secondaire d'incrémenter son opérande. En revanche, l'opérateur préfixe ++ évalue la valeur incrémentée de son opérande.

int a, b;
a = 1;
b = a++;   // b is 1, a is 2
b = ++a;   // b is 3, a is 3

Ce comportement du suffixe L'opérateur ++ est documenté dans la section 6.5.2.4p2 de Norme C :

Le résultat du suffixe L'opérateur ++ est la valeur de l'opérande. En tant qu'effet secondaire, la valeur de l'objet opérande est incrémentée (c'est-à-dire la valeur 1 du type approprié y est ajouté). Voir les discussions sur opérateurs additifs et affectation de composés pour plus d'informations sur les contraintes, les types et les conversions et les effets de opérations sur les pointeurs. Le calcul de la valeur du résultat est séquencé avant l'effet secondaire de la mise à jour du valeur de l'opérande. En ce qui concerne un appel de fonction à séquence indéterminée, l'opération de postfix ++ est une évaluation unique. Postfix ++ sur un objet de type atomique est une opération de lecture-modification-écriture avec une sémantique d'ordre mémoire memory_order_seq_cst.

Et l'opérateur préfixe ++ est documenté dans la section 6.5.3.1p2:

La valeur de l'opérande du préfixe L'opérateur ++ est incrémenté. Le résultat est la nouvelle valeur de l'opérande après incrémentation. L'expression ++ E équivaut à (E + = 1) . Voir les discussions sur les opérateurs additifs et l'affectation des composés pour plus d'informations sur contraintes, types, effets secondaires, conversions et effets de opérations sur les pointeurs.


0 commentaires

2
votes

La priorité se produit lors de l ' analyse . Cela signifie que ++ s'applique à a , pas à b = a .

Mais ++ signifie post incrémentation, donc effectuée après un est évalué pour être attribué à b

Si vous voulez que les deux prennent la valeur 2 effectuer une pré-incrémentation:

b = ++a;


0 commentaires

3
votes

La préséance uniquement détermine quels opérateurs sont regroupés avec quels opérandes lors de l'analyse. Il ne contrôle pas l'ordre d'évaluation. ++ ayant une priorité plus élevée que = signifie seulement que b = a ++ est analysé comme b = (a ++) plutôt que (b = a) ++ .

L'opérateur ++ (formes unaire et suffixe) a un résultat et un effet secondaire . Dans l'expression b = a ++ , le résultat de a ++ est la valeur actuelle de a - c'est ce qui est attribué à b . L ' effet secondaire de a ++ est d'ajouter 1 à a .

L'ordre dans lequel l'affectation à b et la mise à jour vers a se produisent est non spécifié . Le plus simple est

b <- a + 1
a <- a + 1

mais ce qui suit est également autorisé:

tmp <- a
a <- a + 1
b <- tmp

Le résultat de ++ a est la valeur actuelle de a plus 1, et l'effet secondaire est d'ajouter 1 à a . Ne supposez pas que dans une expression comme b = ++ a que a est mis à jour avant b . Encore une fois, l'ordre d'évaluation pourrait être quelque chose comme

b <- a
a <- a + 1

L'ordre d'évaluation réel dépend de votre compilateur, des paramètres d'optimisation, même du code environnant.

Les seuls opérateurs qui forcent l'évaluation de gauche à droite des expressions sont && , || , ?: et opérateurs de virgule.


0 commentaires