OVH Cloud OVH Cloud

[newbie] problème débile

64 réponses
Avatar
Azuriel
Est-ce possible de déclarer une propriété de même classe que celle qui
la possède ?

class A
{
A a;
};

ne compile pas.

4 réponses

3 4 5 6 7
Avatar
kanze
Sylvain wrote:
Y'a des faux copilos et du faux code maintenant ? Whouaa,
j'apprend quelque chose tous les jours. Merci Sylvain.


tu as mal lu / compris -- il y a l'approche théorique cadré et
décrit par la norme et il y a l'expérience (la vraie vie).


En fait, il y a de l'expérience, et il y a de l'expérience.
L'expérience m'a appris, par exemple, que si ce n'est pas écris,
je ne peux pas y compter. (Parfois même quand c'est écrit,
d'ailleurs, on a des surprises.) L'expérience m'a appris la
valeur d'un contrat, si je veux compter sur quelque chose. Et
l'expérience m'a appris que la plupart des fournisseurs de
compilateur considérer la norme comme faisant plus ou moins
partie du contrat.

L'expérience m'a aussi appris que compter que la prochaine
version du compilateur reproduit les aléas de la version
actuelle ne marchait pas à longue échéance.

Ça, c'est de la vraie vie. Ne pas se limiter à un seul
compilateur, et ce qu'il fait par hazard avec le code que je
l'ai passé jusqu'ici.

En fait, je travaille surtout avec g++ et Sun CC, mais je porte
aussi une bonne partie de mon code à VC++. Justement, pour ne
pas me limiter à ce qui se fait sous Solaris, et uniquement ce
qui se fait sous Solaris. Ce qui tombe bien, parce qu'il y a six
mois, il y a eu une décision ici de migrer à Linux pour
certaines choses.

et pour résumer les 2 pts: je me cogne de savoir ce qu'un
compilo que je n'utiliserais jamais estime indéfini.


Tu n'utilises aucun compilateur ? Car c'est, à ma
connaîssance, un comportement indéfini dans tous les
compilateurs.


ta connaissance n'est donc pas universelle.


Certes, mais jusqu'ici, personne n'a pu nous montrer une
exception. VC++, peut-être, mais ce n'est pas prouvé, d'une côté
ou de l'autre.

[...]
Une référence ne change pas d'identité.


pas spontanément mais on peut lui faire changer.


J'aimerais bien voir comment ?

Comme James l'a dit et répété, le compilateur a totalement
le droit d'ignorer et optimiser (lire supprimer) le test
"if(&ref != NULL)" car il "sait" à l'avance que c'est
"impossible".


3ième répet.: "tester cette valeur ne conduira pas à un code
très clean mais bon ..."


Ce qui n'adresse pas la question ? Ici, il s'avère que 1) sur
deux compilateurs très répandu, au moins, le test ne donne pas
le résultat éscompté, 2) que ce comportement est tout à conforme
à ce que quelqu'un qui connaît le C++ s'attend, et 3) que même
si le test marche dans certains cas simples avec VC++, on ne
sait pas s'il est garanti de marcher dans tous les cas, y
compris avec des patchs à venir, à ne pas parler des versions
futures.

int& r = *(int*)0;
Quelle est l'utilité de r ?


là ici ? j'en ai aucune idée.

Plus sérieusement, dans le cas du noeud de btree, qu'est-ce
qui empêche d'utiliser this plutôt que NULL. C'est permi par
la norme et on obtient le résultat voulu.


perso, j'utiliserais (pour un noeud) des ptr et non des refs...


Comme c'est décrit dans tous les livres, n'est-ce pas ? Si pour
la simple raison que qui voit une référence, et connaît le C++,
part du principe qu'elle n'est pas nulle. Utiliser donc les
références nulles ne sert donc qu'à l'obfuscation. (Ou à faire
croire qu'on ne connaît pas le C++.)

--
James Kanze (GABI Software) email:
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
Jean-Marc Bourguet
Gabriel Dos Reis writes:

"kanze" writes:

[...]

| > pour qui écrit un sample jamais publié (surtout pas utilisé)
| > c'est surement d'une haute importance; quand on est derrière
| > un vrai compilo pour du vrai code, le comportement est tout à
| > fait complètement défini.
|
| Avec le compilateur CenterLine, oui. Il est garanti de provoquer
| un message d'erreur. Avec les autres compilateurs, je ne sais
| pas. Je ne vois rien de garantie dans la documentation de Sun
| CC, ni dans celle de g++. (Je n'ai rien vu dans la documentation
| de VC++ non plus, mais je ne l'ai pas tout lue.)

Depuis des années, GCC exploite activement ces genres de
fonctionnement indéfini : si tu déréférences un pointeur, GCC en
déduit qu'il n'est pas nul (tu n'aurais pas dû le faire sinon) ; par
conséquent, l'optimizateur va virer des codes et autres choses sur la
base de cette inférence.


J'ai fait quelques essais, c'est amusant.

if (p == 0) {
x = 1;
}
f(p->x);
if (p == 0) {
x = 2;
}

le second test est supprimé, pas le premier. Il est à mon avis conforme de
supprimer les deux, mais je suppose que ce n'est pas fait pour éviter qu'un
comportement indéfini ait des effets antérieurs à son exécution.

if (p == 0) {
x = 1;
}
p->f();
if (p == 0) {
x = 2;
}

le premier test n'est pas supprimé. Le second test ne l'est que si f est
virtuelle. Je vois deux causes possibles (et non contradictoires): on veut
continuer à faire fonctionner quelque chose de pas garanti mais utilisé par
certains; le code intermédiaire sur lequel fonctionne l'optimiseur
n'indique pas qu'un appel de fonction membre implique que le pointeur n'est
pas nul même si le membre en question n'est pas virtuel.

Utiliser des références à apparemment le même effet qu'utiliser un
pointeur. g++ n'a pas l'air de considérer d'office que les références sont
non nulles dans ce contexte.

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

Avatar
Gabriel Dos Reis
"kanze" writes:

| Gabriel Dos Reis wrote:
| > "kanze" writes:
|
| > [...]
|
| > | > pour qui écrit un sample jamais publié (surtout pas utilisé)
| > | > c'est surement d'une haute importance; quand on est derrière
| > | > un vrai compilo pour du vrai code, le comportement est tout à
| > | > fait complètement défini.
|
| > | Avec le compilateur CenterLine, oui. Il est garanti de provoquer
| > | un message d'erreur. Avec les autres compilateurs, je ne sais
| > | pas. Je ne vois rien de garantie dans la documentation de Sun
| > | CC, ni dans celle de g++. (Je n'ai rien vu dans la documentation
| > | de VC++ non plus, mais je ne l'ai pas tout lue.)
|
| > Depuis des années, GCC exploite activement ces genres de
| > fonctionnement indéfini : si tu déréférences un pointeur, GCC en
| > déduit qu'il n'est pas nul (tu n'aurais pas dû le faire sinon) ; par
| > conséquent, l'optimizateur va virer des codes et autres choses sur la
| > base de cette inférence.
|
| C'est ce que je m'attendrais d'un bon compilateur. (Encore que
| ce n'est pas si évident à implémenter, si le compilateur utilise
| un back-end et un optimisateur qui a été conçu pour C.)

GCC a un seul middle-end :-)
[il y autant de backend que de platforms supportés]
Mais cette optimization est implémentée dans le middle-end.

Un exception est faite pour Java, dans GCC.

-- Gaby
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

[...]

| J'ai fait quelques essais, c'est amusant.
|
| if (p == 0) {
| x = 1;
| }
| f(p->x);
| if (p == 0) {
| x = 2;
| }
|
| le second test est supprimé, pas le premier. Il est à mon avis conforme de
| supprimer les deux, mais je suppose que ce n'est pas fait pour éviter qu'un
| comportement indéfini ait des effets antérieurs à son exécution.

Je crois qu'à partir du moment où il peut être prouvé que le
fonctionnement indéfini aura lieu, l'implémentation est libre de faire
tout ce qu'elle veut même avant l'évaluation de l'expression qui
provoquerait le fonctionnement indéfini.

À mon avis, ce n'est pas fait simplement parce que l'implémentation de
l'époque (~ 1999) était plus dans le « forward propagation » que dans
le « backward propagation. »

| if (p == 0) {
| x = 1;
| }
| p->f();
| if (p == 0) {
| x = 2;
| }
|
| le premier test n'est pas supprimé. Le second test ne l'est que si f est
| virtuelle. Je vois deux causes possibles (et non contradictoires): on veut
| continuer à faire fonctionner quelque chose de pas garanti mais utilisé par
| certains; le code intermédiaire sur lequel fonctionne l'optimiseur
| n'indique pas qu'un appel de fonction membre implique que le pointeur n'est
| pas nul même si le membre en question n'est pas virtuel.
|
| Utiliser des références à apparemment le même effet qu'utiliser un
| pointeur. g++ n'a pas l'air de considérer d'office que les références sont
| non nulles dans ce contexte.

Ce ne sont pas des décisions « exprès » -- c'est juste que le
framework n'est pas suffisamment travaillé.

-- Gaby
3 4 5 6 7