Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec deux
this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A {
A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
Ce code marchera (contraitement a ton exemple qui met bien les point
sur les 'i' ;-), mais je pense que la norme lui attribue quand meme
un UB, p etant un alias sur D* mais de type effectif A* au meme
titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en cours
de construction
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
c'est dans F::F() que tu crees l'alias en appellant B::B() avec deux
this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A {
A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
Ce code marchera (contraitement a ton exemple qui met bien les point
sur les 'i' ;-), mais je pense que la norme lui attribue quand meme
un UB, p etant un alias sur D* mais de type effectif A* au meme
titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en cours
de construction
Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec deux
this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A {
A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
Ce code marchera (contraitement a ton exemple qui met bien les point
sur les 'i' ;-), mais je pense que la norme lui attribue quand meme
un UB, p etant un alias sur D* mais de type effectif A* au meme
titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en cours
de construction
Jean-Marc Bourguet wrote:Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec deux
this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A {
A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
Ce code marchera (contraitement a ton exemple qui met bien les point
sur les 'i' ;-), mais je pense que la norme lui attribue quand meme
un UB, p etant un alias sur D* mais de type effectif A* au meme
titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en cours
de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A {
A(D* p);
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
c'est dans F::F() que tu crees l'alias en appellant B::B() avec deux
this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A {
A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
Ce code marchera (contraitement a ton exemple qui met bien les point
sur les 'i' ;-), mais je pense que la norme lui attribue quand meme
un UB, p etant un alias sur D* mais de type effectif A* au meme
titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en cours
de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A {
A(D* p);
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Jean-Marc Bourguet wrote:Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec deux
this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A {
A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
Ce code marchera (contraitement a ton exemple qui met bien les point
sur les 'i' ;-), mais je pense que la norme lui attribue quand meme
un UB, p etant un alias sur D* mais de type effectif A* au meme
titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en cours
de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A {
A(D* p);
virtual void f();
};
struct D : A {
D(): A(this) {} // alias
virtual void f();
};
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Laurent Deniau writes:Jean-Marc Bourguet wrote:Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec
deux this avec deux types statiques differents mais le meme
type effectif. Donc p->f() invoque un B::f() qui n'exite pas.
Bien vu, ceci dit tu n'as pas besoin de l'heritage multiple
pour avoir le UB:
struct A { A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas
voulu virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
Ce code marchera (contraitement a ton exemple qui met bien les
point sur les 'i' ;-), mais je pense que la norme lui attribue
quand meme un UB, p etant un alias sur D* mais de type effectif
A* au meme titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe
de l'exemple de la norme : le p dans A::A designe le sous-objet
en cours de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A { A(D* p); virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Pour moi, p designe autre chose que le sous-objet en cours de
contruction,
c'est donc un UB.
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
c'est dans F::F() que tu crees l'alias en appellant B::B() avec
deux this avec deux types statiques differents mais le meme
type effectif. Donc p->f() invoque un B::f() qui n'exite pas.
Bien vu, ceci dit tu n'as pas besoin de l'heritage multiple
pour avoir le UB:
struct A { A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas
voulu virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
Ce code marchera (contraitement a ton exemple qui met bien les
point sur les 'i' ;-), mais je pense que la norme lui attribue
quand meme un UB, p etant un alias sur D* mais de type effectif
A* au meme titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe
de l'exemple de la norme : le p dans A::A designe le sous-objet
en cours de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A { A(D* p); virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Pour moi, p designe autre chose que le sous-objet en cours de
contruction,
c'est donc un UB.
Laurent Deniau writes:Jean-Marc Bourguet wrote:Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec
deux this avec deux types statiques differents mais le meme
type effectif. Donc p->f() invoque un B::f() qui n'exite pas.
Bien vu, ceci dit tu n'as pas besoin de l'heritage multiple
pour avoir le UB:
struct A { A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas
voulu virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
Ce code marchera (contraitement a ton exemple qui met bien les
point sur les 'i' ;-), mais je pense que la norme lui attribue
quand meme un UB, p etant un alias sur D* mais de type effectif
A* au meme titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe
de l'exemple de la norme : le p dans A::A designe le sous-objet
en cours de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A { A(D* p); virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Pour moi, p designe autre chose que le sous-objet en cours de
contruction,
c'est donc un UB.
Jean-Marc Bourguet wrote:Laurent Deniau writes:Jean-Marc Bourguet wrote:Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec
deux this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A { A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
Ce code marchera (contraitement a ton exemple qui met bien les
point sur les 'i' ;-), mais je pense que la norme lui attribue
quand meme un UB, p etant un alias sur D* mais de type effectif
A* au meme titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en
cours de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A { A(D* p); virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Pour moi, p designe autre chose que le sous-objet en cours de
contruction,
Et pourtant non, comme dans mon premier exemple.c'est donc un UB.
Je suis d'accord ;-) Par rapport mon exemple precedent je n'ai fait que
rendre explicite l'alias. Voila pourquoi je voulais savoir si le premier
exemple avait aussi un UB, parce que concretement c'est la meme chose.
Je trouve que les deux devraient etre des UB, que l'alias soit explicite
ou implicite, notament parce que ni l'un, ni l'autre ne font ce qui est
attendu - invoquer D::f() - si p n'etait pas this lui-meme (certe ce
n'est pas une raison en soit).
Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
c'est dans F::F() que tu crees l'alias en appellant B::B() avec
deux this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A { A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
Ce code marchera (contraitement a ton exemple qui met bien les
point sur les 'i' ;-), mais je pense que la norme lui attribue
quand meme un UB, p etant un alias sur D* mais de type effectif
A* au meme titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en
cours de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A { A(D* p); virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Pour moi, p designe autre chose que le sous-objet en cours de
contruction,
Et pourtant non, comme dans mon premier exemple.
c'est donc un UB.
Je suis d'accord ;-) Par rapport mon exemple precedent je n'ai fait que
rendre explicite l'alias. Voila pourquoi je voulais savoir si le premier
exemple avait aussi un UB, parce que concretement c'est la meme chose.
Je trouve que les deux devraient etre des UB, que l'alias soit explicite
ou implicite, notament parce que ni l'un, ni l'autre ne font ce qui est
attendu - invoquer D::f() - si p n'etait pas this lui-meme (certe ce
n'est pas une raison en soit).
Jean-Marc Bourguet wrote:Laurent Deniau writes:Jean-Marc Bourguet wrote:Laurent Deniau writes:c'est dans F::F() que tu crees l'alias en appellant B::B() avec
deux this avec deux types statiques differents mais le meme type
effectif. Donc p->f() invoque un B::f() qui n'exite pas. Bien vu,
ceci dit tu n'as pas besoin de l'heritage multiple pour avoir le UB:
struct A { A(A*p) { p->f(); } // invoque A::f(p), Ok mais pas voulu
virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
Ce code marchera (contraitement a ton exemple qui met bien les
point sur les 'i' ;-), mais je pense que la norme lui attribue
quand meme un UB, p etant un alias sur D* mais de type effectif
A* au meme titre que this...
Je crois que c'est bien defini. C'est la partie que j'ai coupe de
l'exemple de la norme : le p dans A::A designe le sous-objet en
cours de construction
Juste, mon exemple etait trop simpliste, mais que penses-tu de:
struct D;
struct A { A(D* p); virtual void f(); };
struct D : A { D(): A(this) {} // alias virtual void f(); };
A::A(D* p) { p->f(); } // appelle A::f() au lieu de D::f()!
cette fois-ci l'alias est explicite mais le type effectif (et le
comportement) est le meme. UB or not UB?
Pour moi, p designe autre chose que le sous-objet en cours de
contruction,
Et pourtant non, comme dans mon premier exemple.c'est donc un UB.
Je suis d'accord ;-) Par rapport mon exemple precedent je n'ai fait que
rendre explicite l'alias. Voila pourquoi je voulais savoir si le premier
exemple avait aussi un UB, parce que concretement c'est la meme chose.
Je trouve que les deux devraient etre des UB, que l'alias soit explicite
ou implicite, notament parce que ni l'un, ni l'autre ne font ce qui est
attendu - invoquer D::f() - si p n'etait pas this lui-meme (certe ce
n'est pas une raison en soit).
Laurent Deniau wrote:
- toute resolution de methode basee sur *this* est statique.
this->f() invoque T::f() ou T* est le type de this ou celui d'un
parent. (Est-ce que ca leverait la necessite de modifier les __vtbl?)
Laurent Deniau wrote:
- toute resolution de methode basee sur *this* est statique.
this->f() invoque T::f() ou T* est le type de this ou celui d'un
parent. (Est-ce que ca leverait la necessite de modifier les __vtbl?)
Laurent Deniau wrote:
- toute resolution de methode basee sur *this* est statique.
this->f() invoque T::f() ou T* est le type de this ou celui d'un
parent. (Est-ce que ca leverait la necessite de modifier les __vtbl?)
Laurent Deniau wrote:Jean-Marc Bourguet wrote:
Donc quand Gaby dit que un B* devient un A* en entrant dans A::~A(),
il a complement raison.
Ce qui veut dire ensuite que la resolution des
methodes (virtuelle ou non) reste inchange: pas de semantique
particuliere dans les ctor/dtor.
Et donc comme dit Gaby, la regle de James est compliquee voir illogique
car cela n'a rien a voir avec la semantique de resolution des appels
virtuels dans les ctor/dtor. Seulement avec la transition du type de
this. Du moins c'est ma conclusion pour l'instant. Des reclamations ? ;-)
Laurent Deniau wrote:
Jean-Marc Bourguet wrote:
Donc quand Gaby dit que un B* devient un A* en entrant dans A::~A(),
il a complement raison.
Ce qui veut dire ensuite que la resolution des
methodes (virtuelle ou non) reste inchange: pas de semantique
particuliere dans les ctor/dtor.
Et donc comme dit Gaby, la regle de James est compliquee voir illogique
car cela n'a rien a voir avec la semantique de resolution des appels
virtuels dans les ctor/dtor. Seulement avec la transition du type de
this. Du moins c'est ma conclusion pour l'instant. Des reclamations ? ;-)
Laurent Deniau wrote:Jean-Marc Bourguet wrote:
Donc quand Gaby dit que un B* devient un A* en entrant dans A::~A(),
il a complement raison.
Ce qui veut dire ensuite que la resolution des
methodes (virtuelle ou non) reste inchange: pas de semantique
particuliere dans les ctor/dtor.
Et donc comme dit Gaby, la regle de James est compliquee voir illogique
car cela n'a rien a voir avec la semantique de resolution des appels
virtuels dans les ctor/dtor. Seulement avec la transition du type de
this. Du moins c'est ma conclusion pour l'instant. Des reclamations ? ;-)