2 votes

Préséance des opérateurs d'incrémentation post et pré

Il existe un code :

#include <iostream>

class Int {
public:
    Int() : x(0) {}
    Int(int x_) : x(x_) {}
    Int& operator=(const Int& b) {
        std::cout << "= from " << x << " = " << b.x << std::endl;
        x = b.x;
    }
    Int& operator+=(const Int& b) {
        std::cout << "+= from " << x << " + " << b.x << std::endl;
        x += b.x;
        return *this;
    }
    Int& operator++() {
        std::cout << "++ prefix " << x << std::endl;
        ++x;
        return *this;
    }
    Int operator++(int) {
        std::cout << "++ postfix " << x << std::endl;
        Int result(*this);
        ++x;
        return result;
    }
private:
    int x;

};

Int operator+(const Int& a, const Int& b) {
    std::cout << "operator+" << std::endl;
    Int result(a);
    result += b;
    return result;
}

int main() {
    Int a(2), b(3), c(4), d;
    d = ++a + b++ + ++c;
    return 0;
}

Résultat :

++ prefix 4
++ postfix 3
++ prefix 2
operator+
+= from 3 + 3
operator+
+= from 6 + 5
= from 0 = 11

Pourquoi l'opérateur postfixe n'est-il pas exécuté avant l'opérateur préfixe (++ préfixe 4) alors que la priorité de l'opérateur postfixe est plus élevée que celle de l'opérateur préfixe ?

Il a été compilé par g++.

4voto

L'ordre d'évaluation des différents opérandes n'est pas spécifié, ce qui signifie que le compilateur est libre de réorganiser l'évaluation des opérandes. ++a , b++ y ++c les sous-expressions à sa guise. La préséance des opérateurs n'a pas vraiment d'impact dans cet exemple.

Cela a un effet si vous essayez d'écrire ++i++ (où i est un int ) qui seront regroupés comme suit ++(i++) et la compilation échouera car la sous-expression i++ est une valeur r et l'incrémentation du préfixe nécessite une valeur l. Si la préséance était inversée, cette expression serait compilée (et provoquerait un comportement indéfini).

0voto

wcochran Points 1150

Postfixe ++ a la priorité la plus élevée dans l'expression ++a + b++ + ++c mais + a la priorité la plus faible et est associatif à gauche. Cette expression peut s'écrire de manière équivalente (++a) + (b++) + (++c) (chaque ++ fait partie d'une sous-expression différente), ce qui explique pourquoi ++a est évaluée en premier. Il suffit de parcourir/évaluer l'arbre d'analyse correspondant pour que l'ordre d'évaluation devienne évident :

           E
         / | \
        /  |  E
       /   |  | \
      E    +  ++  c
    / | \
   /  |  \
  E   +   E
 / \     / \
++  a   b  ++

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X