Opérateur virgule
Le
Christophe DUVERGER

Bonjour,
Le document n1905 dit concernant l'opérateur virgule au §5.18: "All
side effects (1.9) of the left expression, except for the destruction
of temporaries (12.2), are performed before the evaluation of the
right expression.".
Pourtant je constate le contraire avec g++ 4.5.2 avec le code suivant:
class A {
public:
int val;
A(const int& n) : val(n) {}
};
class B {
};
A operator , (A a, int* const n) {
*n = a.val;
std::cout << "n = " << *n << std::endl;
return a;
}
A operator , (A a, A b) {
std::cout << "(b % " << a.val << "), (b % " << b.val << ")" <<
std::endl;
return b;
}
A operator % (B b, int n) {
std::cout << "b % " << n << std::endl;
return A(n);
}
int main() {
B b;
int n = 1;
(b % n, b % 2, &n, b % n);
return 0;
}
qui donne le résultat:
b % 1
b % 2
b % 1
(b % 1), (b % 2)
n = 2
(b % 2), (b % 1)
C'est à dire que l'expression la plus à droite a été évaluée av=
ant
l'affectation de n juste à gauche, contrairement à la n1905.
Ai-je mal compris ou mal codé ?
Merci de votre aide.
Le document n1905 dit concernant l'opérateur virgule au §5.18: "All
side effects (1.9) of the left expression, except for the destruction
of temporaries (12.2), are performed before the evaluation of the
right expression.".
Pourtant je constate le contraire avec g++ 4.5.2 avec le code suivant:
class A {
public:
int val;
A(const int& n) : val(n) {}
};
class B {
};
A operator , (A a, int* const n) {
*n = a.val;
std::cout << "n = " << *n << std::endl;
return a;
}
A operator , (A a, A b) {
std::cout << "(b % " << a.val << "), (b % " << b.val << ")" <<
std::endl;
return b;
}
A operator % (B b, int n) {
std::cout << "b % " << n << std::endl;
return A(n);
}
int main() {
B b;
int n = 1;
(b % n, b % 2, &n, b % n);
return 0;
}
qui donne le résultat:
b % 1
b % 2
b % 1
(b % 1), (b % 2)
n = 2
(b % 2), (b % 1)
C'est à dire que l'expression la plus à droite a été évaluée av=
ant
l'affectation de n juste à gauche, contrairement à la n1905.
Ai-je mal compris ou mal codé ?
Merci de votre aide.
Ce paragraphe s'applique à la version définie par le langage, pas à ceux
que tu définis toi-même; c'est le cas aussi pour && et || et c'est une
raison pour lesquelles il faut réfléchir à plusieurs fois avant d'utiliser
la possibilité de surcharge.
A+
--
Jean-Marc
FAQ de fclc++: http://web.archive.org/web/*/http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Toujours dans le document n1905, on peut lire au §13.5 - 6 : "It is
not possible to change the precedence, grouping, or number of operands
of operators.".
Donc normalement, le comportement associatif de l'opérateur virgule
devrait être conservé.
Christophe
Ca ne parle pas de la presence ou non de points de sequencement. Les
operateurs definis par l'utilisateur sont des fonctions comme les autres
pour tout ce qui est semantique (ok, -> a un comportement particulier)
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index. html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Effectivement, §1.9 note 14: 14) "When one of these operators is
overloaded (clause 13) in a valid context, thus designating a user-
defined operator function, the expression designates a function
invocation, and the operands form an argument list, without an implied
sequence point between them."
Et §8.3.6 - 9: "The order of evaluation of function arguments is
unspecified."
Merci
Christophe