OVH Cloud OVH Cloud

Pas d'operateur de comparaison par defaut

75 réponses
Avatar
Olivier Croquette
Salut

Le compilateur génére automatiquement certains opérateurs par défaut
pour les classes qui ne le font pas automatiquement.
Sauf erreur de ma part, il s'agit de:
- constructeur par défaut (Classe::Classe())
- constructeur de recopie (Classe::Classe(const Class&))
- affectation (Classe::operator = (const Classe&))

Pourquoi n'est-il pas prévu qu'il fasse de même pour l'opérateur (par
exemple) de comparaison (==)?
L'implémentation naturelle serait de considérer ses attributs un à un,
tout comme pour la recopie.
Y a-t'il une raison?

10 réponses

4 5 6 7 8
Avatar
Sylvain
Gabriel Dos Reis wrote on 10/09/2006 22:32:

Nous avons pensé au problème en long, en large, et en travers. Il y a
puet-être une solution, mais il faudra attendre 2010 ou plus.


on pourrait dire "c'est heureux !" car on a vu des dinosaures s'enliser
plus longtemps.

on peut aussi être consterné ! *Vous* avez pensé et *il* (le petit
peuple) devra attendre 2010.

finalement ton laconisme est moins détestable.

Sylvain.

Avatar
Sylvain
Gabriel Dos Reis wrote on 10/09/2006 22:29:
Sylvain writes:

| Franck Branjonneau wrote on 02/09/2006 23:36:
| >
| >> "==" est univoque
| > Non.
|
| tu fais bien de ne pas détailler, ça évite les bourdes.
| (si '0' n'est plus égal à '0' et '1' à '1' on cours au pb).

volatile int x = 0;

assert (x == x);

?


un code débile pourquoi ?

Sylvain.

Avatar
Gabriel Dos Reis
Sylvain writes:

[...]

| on peut aussi être consterné ! *Vous* avez pensé et *il* (le petit
| peuple) devra attendre 2010.

C'est une estimation de la date prévue pour la prochaine version de C++.
Ton compilateur peut l'avoir plus tôt ou plus tard. YMMV.

-- Gaby
Avatar
Gabriel Dos Reis
Sylvain writes:

| Gabriel Dos Reis wrote on 10/09/2006 22:29:
| > Sylvain writes:
| > | Franck Branjonneau wrote on 02/09/2006 23:36:
| > | >
| > | >> "==" est univoque
| > | > Non.
| > | | tu fais bien de ne pas détailler, ça évite les bourdes.
| > | (si '0' n'est plus égal à '0' et '1' à '1' on cours au pb).
| > volatile int x = 0;
| > assert (x == x);
| > ?
|
| un code débile pourquoi ?

disons qu'il ne fait que te suivre en la matière.

-- Gaby
Avatar
Olivier Croquette
Gabriel Dos Reis wrote:

C'est une estimation de la date prévue pour la prochaine version de C++.
Ton compilateur peut l'avoir plus tôt ou plus tard. YMMV.


As-tu des informations qui indiquent que la comparaison membre à membre
automatique sera possible dans la prochaine verson de C++? Si oui,
lesquelles?

Avatar
kanze
Gabriel Dos Reis wrote:
Olivier Croquette writes:

[...]

| Mais en ce qui me concerne, le problème n'est pas tant
d'avoir un | opérateur *implicite* de comparaison membre à
membre, mais d'en avoir | un tout court.

En effet.

Nous avons pensé au problème en long, en large, et en travers.
Il y a puet-être une solution, mais il faudra attendre 2010 ou
plus.


Est-ce que tu as un numéro de document ? Moi aussi, j'ai un
souvenir d'avoir vu quelque chose de ce genre, mais je n'arrive
pas à le rétrouver (à partir des documents cités dans N2011).

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Gabriel Dos Reis
Olivier Croquette writes:

| Gabriel Dos Reis wrote:
|
| > C'est une estimation de la date prévue pour la prochaine version de C++.
| > Ton compilateur peut l'avoir plus tôt ou plus tard. YMMV.
|
| As-tu des informations qui indiquent que la comparaison membre à
| membre automatique sera possible dans la prochaine verson de C++?

Oui.

| Si oui, lesquelles?

discussions dans le EWG à la dernière réunion du comité.

-- Gaby
Avatar
Marc Boyer
Le 06-09-2006, Sylvain a écrit :
Marc Boyer wrote on 06/09/2006 14:24:

btw, c'est ce qui n'explique pas - à mes yeux - les réactions envers un
(mauvais) opérateur implicite basé sur memcmp; l' "intelligence" de
l'opération serait semblable.


Hormis: le padding et le cas du NaN.
Donc, il serait pire.


- on a déjà indiqué que le problème du padding peut être réglé par une
mise à zéro de toute la zone mémoire de la struct avant la recopie.


Oui, on ajoute des contraintes sur l'opérateur de copie pour régler
le problème de l'opérateur de comparaison.

- NaN n'est pas une valeur, donc rappeler que NaN n'est pas unique était
une porte ouverte; par contre ayant un entier évalué comme NaN (par
_isnan) sa copie par memcmp sera également évaluée comme NaN.


Oui, mais un autre intervenant n'a-t-il pas souligné que la
comparaison de deux NaN, même égaux bits à bit, devait être
évaluée comme fausse ?

Et puis il y a aussi les attributs *mutable*, qu'il va falloir
ignorer.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)



Avatar
Sylvain
Marc Boyer wrote on 11/09/2006 15:45:

- on a déjà indiqué que le problème du padding peut être réglé par une
mise à zéro de toute la zone mémoire de la struct avant la recopie.


Oui, on ajoute des contraintes sur l'opérateur de copie pour régler
le problème de l'opérateur de comparaison.


c'est un choix de consistance.

soit on pense que c'est déjà le souk avec une opérateur de copie ("qui
existe toujours") et on ne change rien qui permettrait un opérateur de
comparaison ("qui n'existera jamais").

soit on imagine un petit clean-up qui faciliterait les choses -
considérant que ce clean-up est assez souvent nécessaire (et laborieux
du fait de la non possibilité d'appeler un constructeur de même niveau
depuis un cst) ça ferait d'une pierre 2 trucs. (il paraitrait même que
d'autres langages ont ce clean-up systématique).

- NaN n'est pas une valeur, donc rappeler que NaN n'est pas unique était
une porte ouverte; par contre ayant un entier évalué comme NaN (par
_isnan) sa copie par memcmp sera également évaluée comme NaN.


Oui, mais un autre intervenant n'a-t-il pas souligné que la
comparaison de deux NaN, même égaux bits à bit, devait être
évaluée comme fausse ?


merci de le citer !!! lui (nous) répondre pourquoi aurait été encore
plus sympa; pour ma part je ne peux pas reproduire son résultat et je ne
l'explique pas; je le tiens, en l'état actuel, pour une erreur de son
compilo .

Et puis il y a aussi les attributs *mutable*, qu'il va falloir
ignorer.


ah, volatile, mutable, à qui le prochain ??

rappelle-moi, ou corrige moi si besoin, un attribut "mutable" est un
machin qui a le droit de changer de valeur dans un contexte const, non ?
cela ne concerne que le compilo et les contrôles qu'il fera sur l'accès
à cette variable - en aucun cas la façon dont elle sera mappée en
mémoire (comme sa non prise en compte dans un sizeof, ou "ailleurs" non
contiguë aux autres données).

quel rapport donc entre ce mutable et le fait que 2 instances ayant tous
leurs champs égaux (bit à bit) seront égales tandis que si elles
différent par la valeur d'un champ, même marqué mutable, elles seront
vues différentes ???

Sylvain.


Avatar
Sylvain
Gabriel Dos Reis wrote on 11/09/2006 04:21:
Sylvain writes:

| Gabriel Dos Reis wrote on 10/09/2006 22:29:
| > Sylvain writes:
| > | Franck Branjonneau wrote on 02/09/2006 23:36:
| > | >
| > | >> "==" est univoque
| > | > Non.
| > | | tu fais bien de ne pas détailler, ça évite les bourdes.
| > | (si '0' n'est plus égal à '0' et '1' à '1' on cours au pb).
| > volatile int x = 0;
| > assert (x == x);
| > ?
|
| un code débile pourquoi ?

disons qu'il ne fait que te suivre en la matière.


certes Gabriel, mais pourquoi tout ce bavardage, tu aurais pu nous
servir: [1]

a ?= b;
donc Sylvain est un con.

(j'ai isolé pour coter facilement)
le message est à peu près le même et tu gagnes un tour.

hein ? le post était bien *ON TOPIC* ?
allez soyons fou, on n'est plus à 10mn de gaché près; je ne reprendrais
toutefois que mes extraits, l'erreur ne peut être que là!, si pas
convaincu, voir [1] et évidemment la longue prose de Gabriel.

"==" est univoque.

selon le Littré: "Qui n'est susceptible que d'une seule interprétation".
(par opposition à 'équivoque': "Qui peut s'interpréter en différents
sens..."

"==" est bien univoque, il ne serait être interpréter comme "tantôt ça
compare les opérandes", "tantôt ça les additionne".

(si '0' n'est plus égal à '0' et '1' à '1' on cours au pb)

serait-on face à une mutation de bits qui en effet invaliderait cette
présomptueuse affirmation ? '0' serait-il des fois égal à '0' mais des
fois égal à '1' ?...

Gabriel a du nous donner des indices, forcément, il adore les devinettes
(Carambar ne sait pas ce qu'il perd, quel dommage!)

volatile int x = 0;

volatile est l'indice, forcément (bis).

mais est-il ici que pour éviter que le compilo ne balance le test
bizarre qui suit ou signifie-t-il plus ?? oulalah quel mystère !

le texte original doit nous aider ici, le post montre une ligne vide
entre cette déclaration et l'assertion qui suit ! c'est clair, le code
fait qlq chose qu'il nous faut deviner, mais quoi ??

évidemment un contexte clair nous aurait aidé, par exemple:

synchronized (x) {
assert(x == x);
}

aurait indiqué un accès protégé à ce damné x, oui mais, ..., l'énigme
est bien posté sur fr.comp.lang.c++ et ce langage ne contient pas dans
sa syntaxe la moindre protection contre les accès concurrentiels!

c'est en effet quasi stupéfiant, mais, définissant une struct
fournissant son opérateur de copie (qui copiera bien comme il faut les
pointeurs, ou appliquera avec soin un reference counting, pardon un
décompte des références à un objet) ou utilisant le constructeur de
copie par défaut (solide puisque sorti droit de la norme), et bien avec
le code:

S a; // 'S' est la struct en question
...
S b = a;

là ici précisément à la fin de la copie, il y a juste aucune garantie
que le contenu de b (la valeur de toutes ses données membre) soit égal à
celui de a, c'est ballot direz-vous ? non, c'est la norme et c'est très
bien, en tout cas non discutable, ou re-en tout cas pas question à qui
n'a pas fait cette norme de prétendre à la même légèreté.

mais on s'égare, revenons à notre (x == x), se pourrait-il également que
les opérateurs de comparaison, y compris ceux du CRT, ne soient pas
protégés contre les accès concurrentiels ? ben voyons ! bien sur que
l'évaluation de droite peut être interrompue, x peut être trituré, et
l'évaluation de gauche (ou vice-versa, c'est un détail) peut donner
quelque chose de différent.

résumons-nous: une copie ne garantis pas de fournir un clone et un test
de comparaison impliquant un seul objet (au sens large) peut échouer.

est-ce que cela indiquerait que '0' n'est plus égal à '0' ?? que neni,
cela montre seulement que le résultat d'une évaluation est imprévisible
si le contexte n'est pas complètement maîtrisé (ici si l'on n'a pas mis
un verrou sur x).

ok, mais la débilité du machin-chose ?

dans de nombreux cas, on peut déplorer que des développeurs réalisent
des tests totalement non pertinents, qlq asserts assez bateau en début
de méthode et zou, "j'ai tout vérifié", ben non, pas si simple.

un test "assert(x == x);" est débile car complètement inutile et
fondamentalement malsain: il ne donne aucune garantie sur x avant ce
test, rien pendant ce test et rien après ce test; par contre il pourrait
faire échouer le code mais pour une mauvaise raison.

donc un exemple à ne pas "SUIVRE".

Sylvain.

4 5 6 7 8