OVH Cloud OVH Cloud

'this' : used in base member initializer list

80 réponses
Avatar
amerio
Bonjour,
Mon pb doit est le suivant : une classe doit initialisé un de ses membres
avec un pointeur dur elle même :

class B
{
public:
B(class A* pA) : m_pA(pA) {}
private:
class A* m_pA;
}

class A
{
public:
A() : m_B(this) {} // warning 'this' : used in base member
initializer list
private:
const B m_B;
}

Comment eviter le warning (sous VC6) (et d'abord, dois je l'éviter ou
changer de technique ? quel est le risque ?)
Au passage, boost:: utilise cette technique, cf
http://www.boost.org/libs/smart_ptr/sp_techniques.html#weak_without_shared

10 réponses

4 5 6 7 8
Avatar
James Kanze
Gabriel Dos Reis writes:

|> James Kanze writes:

|> | "Alain Naigeon" writes:

|> | |> Par ailleurs, c'est bien vrai que pour quelqu'un qui se pose
|> | |> la question d'utiliser this dans une liste du constructeur,
|> | |> c'est un vrai miracle de tomber sur le paragraphe en
|> | |> question parmi tant d'autres qui parlent des pointeurs...
|> | |> Mais enfin, maintenant qu'on a le texte sous les yeux, c'est
|> | |> tout de même clair qu'il concerne *aussi* this, il me
|> | |> semble.

|> | Il concerne tout pointeur qui est visible.

|> Non. Pas du tout, ce paragraphe concerne toute expression de
|> pointeur.

Toute expression de pointeur qui est autrement légale ?

|> | Il ne répond pas à la question si this est visible ou non.

|> simplement parce que « thjis est visible » est quelque chose
|> que tu viens d'inventer ? Voir le chapitre 3 sur la notion de
|> portée.

D'accord. Je sais que c'est un mot clé, et je sais qu'il n'a donc
pas de « portée ». Je sais aussi que je ne peux pas
l'utiliser partout.

|> | En fait, le paragraphe en question est intéressant par
|> | rapport à this. Parce qu'il rend illégal l'initialisation
|> | des classes de base dans la liste d'initialisation. Puisque
|> | l'intialisation d'une classe de base implique la conversion de
|> | this en pointeur au type de base, quelque chose qui est
|> | explicitement interdit ici (mais explicitement permis ailleurs
|> | -- encore une contradiction dans la norme).

|> ce que tu écris ci-dessus est un pur non sens.

Pas pour tout le monde. C'est en effet quelque chose que j'ai écrit
avant dans comp.std.c++, où au moins une personne (Fergus
Henderson) était d'accord que c'était ce que disait ce passage.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis writes:
|
| |> James Kanze writes:
|
| |> | "Alain Naigeon" writes:
|
| |> | |> Par ailleurs, c'est bien vrai que pour quelqu'un qui se pose
| |> | |> la question d'utiliser this dans une liste du constructeur,
| |> | |> c'est un vrai miracle de tomber sur le paragraphe en
| |> | |> question parmi tant d'autres qui parlent des pointeurs...
| |> | |> Mais enfin, maintenant qu'on a le texte sous les yeux, c'est
| |> | |> tout de même clair qu'il concerne *aussi* this, il me
| |> | |> semble.
|
| |> | Il concerne tout pointeur qui est visible.
|
| |> Non. Pas du tout, ce paragraphe concerne toute expression de
| |> pointeur.
|
| Toute expression de pointeur qui est autrement légale ?

Non. Toute expression de pointeur désignant l'emplacement de l'objet.
Le contexte aidait à comprendre.

| |> | Il ne répond pas à la question si this est visible ou non.
|
| |> simplement parce que « thjis est visible » est quelque chose
| |> que tu viens d'inventer ? Voir le chapitre 3 sur la notion de
| |> portée.
|
| D'accord. Je sais que c'est un mot clé, et je sais qu'il n'a donc
| pas de « portée ».

Ah bon. « je sais que c'est un non sens mais je l'écris quand même ».

-- Gaby
Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis writes:
|
| |> | > et pour couronner le tout, on me parle maintenant de
| |> | > « visiblité de this », quelque chose qui n'a pas de
| |> | > sens.
|
| |> | Je n'ai jamais parlé de visibilité de `this´.
|
| |> Tu as acquiescé par un « yep » lorsque James a sorti le
| |> pigeon de son chapeau.
|
| C'est qu'il ne cherche pas la petite bête, et qu'il a compris ce
| que j'ai voulu dire, et non ce que j'ai dit mot à mot.

Pouf. Quand tu pinailles sur ce que dit la norme et qu'on te prend la
main dans le sac, c'est qu'on cherche la petite bête ?

| Mais bien, je t'accorde que quand on parle de la norme comme ça, il
| vaut mieux être précis dans son langage. Alors, j'accepte les
| torts pour la « portée ».
Avatar
Gabriel Dos Reis
James Kanze writes:

| drkm writes:
|
| |> > et pour couronner le tout, on me parle maintenant de
| |> > « visiblité de this », quelque chose qui n'a pas de
| |> > sens.
|
| |> Je n'ai jamais parlé de visibilité de `this´.
|
| C'est mon erreur. Mais j'aurais cru que le contexte rendait clair que
| j'en parlais de la validité de l'utilisation du mot clé

Le contexte était très clair : on parlait de la norme, et la norme
définit bien ce qu'est portée, visibilité. Dans ce contexte,
« visibilité de 'this' » est simplement un pur non sens.

-- Gaby
Avatar
Alain Naigeon
"drkm" a écrit dans le message news:

"Alain Naigeon" writes:

"drkm" a écrit dans le message news:


Pardon, je n'ai pas été assez clair. Je suis bien sûr d'accord
avec le fait que `this´ puisse « remplir les critères du
paragraphe cité » à certains moments.


Si tu relis le paragraphe, ou son exégèse par Gaby, tu vois aussi
que les *circonstances* de son usage s'appliquent elles aussi à la
liste d'initialisation du constructeur,


D'où tires-tu que les circonstances de son usage s'appliquent elles
aussi à la liste d'initialisation ?


5 Before the lifetime of an object has started but after the storage which
the object will occupy has been allocated34)
[or, ...]
any pointer that refers to the storage location where the object will be [or
was] located
may be used but only in limited ways. Such a pointer refers to allocated
storage (3.7.3.2), and using the
pointer as if the pointer were of type void*, is welldefined.
Such a pointer may be dereferenced but the
resulting lvalue may only be used in limited ways, as described below.

Dans la liste d'initialisation, les circonstances sont, il me semble :
1) la place nécessaire à l'objet en cours de construction est allouée ;
2) même s'il est vrai que la durée de vie de l'objet n'a pas commencé.

Le texte anglais dit clairement (en ordre inverse) que la phrase 2 n'est pas
un problème dès l'instant que la condition exprimée par la phrase 1 est
remplie... que demande le peuple ? ;-)
Mais ça reste vrai qu'il nous fallait Gaby pour deviner où chercher ces
quelques mots dans les centaines de pages de la norme...

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France



Avatar
kanze
"Alain Naigeon" wrote in message
news:<3f13232a$0$5398$...
"drkm" a écrit dans le message news:

"Alain Naigeon" writes:

"drkm" a écrit dans le message news:


Pardon, je n'ai pas été assez clair. Je suis bien sûr d'accord
avec le fait que `this´ puisse « remplir les critères du
paragraphe cité » à certains moments.


Si tu relis le paragraphe, ou son exégèse par Gaby, tu vois aussi
que les *circonstances* de son usage s'appliquent elles aussi à la
liste d'initialisation du constructeur,


D'où tires-tu que les circonstances de son usage s'appliquent
elles aussi à la liste d'initialisation ?


5 Before the lifetime of an object has started but after the storage
which the object will occupy has been allocated34) [or, ...] any
pointer that refers to the storage location where the object will be
[or was] located may be used but only in limited ways. Such a pointer
refers to allocated storage (3.7.3.2), and using the pointer as if the
pointer were of type void*, is welldefined. Such a pointer may be
dereferenced but the resulting lvalue may only be used in limited
ways, as described below.


Ceci ne repond pas à la question : « est-ce que une expression this est
valide à ce moment ? » Tout ce qu'il dit, c'est que si une expression
this est valide, on ne peut s'en servir que d'une façon limitée.

Dans la liste d'initialisation, les circonstances sont, il me semble :
1) la place nécessaire à l'objet en cours de construction est allouée
; 2) même s'il est vrai que la durée de vie de l'objet n'a pas
commencé.


Certes. Mais pour que ce s'applique à une expression this, il faut
qu'une expression this soit valide à cet endroit. Il n'y a rien dans ce
passage qui laisse croire que « this » est une expression valide qui
donne l'adresse de l'objet à construire, et c'était bien ça la question.

Je rapelle que cette discussion a commencé parce que drkm avait cité
§9.3.2/1 de la norme, qui dit « In the BODY of a nonstatic member
function, they keyword this is a non-lvalue expression whose value is
the address of the object for which the function is called » et ensuite
un passage qui laisse croire que la liste d'initialisation ne fait pas
partie du « body » du constructeur.

En fait, évidemment, la définition définitive d'une expression this
(c-à-d le mot clé this) se trouve dans 5.3/1, et elle cite explicitement
des listes d'initialisation. Ayant déterminé que l'expression est
valide, et sa syntaxe, on aperçoit que les restrictions dans §3.8
s'appliquent. Ou s'appliquera, s'il n'y avait pas le renvoie à §12.7,
qui précise des régles différentes en ce qui concerne this -- il y a en
fait une contradiction entre §3.8, où il est dit que « The lifetime of
an object of type T begins when [...] the constructor call has
TERMINATED » et « the program has undefined behavior if [...] the
pointer is implicitly converted to a pointer to a base class type », et
§12.7, où il est dit que « To explicitly or implicitly convert a pointer
(an lvalue) referring to an object of class X to a pointer (reference)
to a direct or indirect base class B of X, the construction of X and the
construction of all of its direct or indirect bases that directly or
indirectly derive from B shal have STARTED [...] »

Si j'ai :

struct B{} ; struct D : B { D() {} } ;

§3.8 dit que la conversion d'un D* en un B* n'est valable qu'une fois le
constructeur de D terminé, et §12.7 dit que c'est valable dès que le
constructeur de D a commencé.

Le texte anglais dit clairement (en ordre inverse) que la phrase 2
n'est pas un problème dès l'instant que la condition exprimée par la
phrase 1 est remplie... que demande le peuple ? ;-)


Le texte anglais que tu as cité parlait d'un « pointer that refers to
the storage location where the object will be located ». Il ne s'adresse
pas au problème de savoir si « this » est un pointeur valide à ce
moment-là. (Pour ce faire, il faut bien régarder §5.3.)

Mais ça reste vrai qu'il nous fallait Gaby pour deviner où chercher
ces quelques mots dans les centaines de pages de la norme...


Je reconnais que Gaby est un expert pour trouver quelques mots et les
citer hors contextes, en leur attribuant une signification que peu
d'autres arrivent à y trouver.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16




Avatar
Gabriel Dos Reis
writes:

| Je reconnais que Gaby est un expert pour trouver quelques mots et les
| citer hors contextes, en leur attribuant une signification que peu
| d'autres arrivent à y trouver.

Je reconnais que James Kanze est expert en la negation des vérités les
plus flagrantes. Mais on se gtardera de ls dire.

-- Gaby
Avatar
drkm
"Alain Naigeon" writes:

"drkm" a écrit dans le message news:


"Alain Naigeon" writes:

"drkm" a écrit dans le message news:


Pardon, je n'ai pas été assez clair. Je suis bien sà »r
d'accord avec le fait que `this´ puisse « remplir les cri tères
du paragraphe cité » à certains moments.


Si tu relis le paragraphe, ou son exégèse par Gaby, tu vois
aussi que les *circonstances* de son usage s'appliquent elles
aussi à la liste d'initialisation du constructeur,


D'où tires-tu que les circonstances de son usage s'appliquent
elles aussi à la liste d'initialisation ?


5 Before the lifetime of an object has started but after the storage
which the object will occupy has been allocated34) [or, ...] any
pointer that refers to the storage location where the object will be
[or was] located may be used but only in limited ways. Such a
pointer refers to allocated storage (3.7.3.2), and using the pointer
as if the pointer were of type void*, is welldefined. Such a
pointer may be dereferenced but the resulting lvalue may only be
used in limited ways, as described below.

Dans la liste d'initialisation, les circonstances sont, il me
semble :
1) la place nécessaire à l'objet en cours de construction est
allouée ;
2) même s'il est vrai que la durée de vie de l'objet n'a pas
commencé.


... ou est déjà terminée.

Mais il s'agit des conditions pour qu'un pointeur doive / puisse
suivre les utilisations décrites dans 3.8/5. On n'y dit pas que
`this' remplit ces conditions dans la liste d'initialisation.

S'il les remplit, comme le dit 5.1/3, ses utilisations doivent alors
se conformer à 3.8/5.

D'où ma question, à laquelle tu n'as pas répondu :

D'où tires-tu que les circonstances de son usage s'appliquent
elles aussi à la liste d'initialisation ?

Le texte anglais dit clairement (en ordre inverse) que la phrase 2
n'est pas un problème dès l'instant que la condition exprimà ©e par la
phrase 1 est remplie... que demande le peuple ? ;-)


Et 5.1/3 dit que `this' utilisé dans la liste d'initialisation
remplit ces conditions.

Mais ça reste vrai qu'il nous fallait Gaby pour deviner où cher cher
ces quelques mots dans les centaines de pages de la norme...


Et James pour citer 5.1/3. ;-p

--drkm




Avatar
drkm
Gabriel Dos Reis writes:

James Kanze writes:

| Gabriel Dos Reis writes:

| |> James Kanze writes:

| |> | Il ne répond pas à la question si this est visible ou n on.

| |> simplement parce que « thjis est visible » est quelque ch ose
| |> que tu viens d'inventer ? Voir le chapitre 3 sur la notion de
| |> portée.

| D'accord. Je sais que c'est un mot clé, et je sais qu'il n'a donc
| pas de « portée ».

Ah bon. « je sais que c'est un non sens mais je l'écris quand m ême ».


Mmm. Je sais que c'est de la démagogie mais je l'écris quand
même...

--drkm

Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| Gabriel Dos Reis writes:

| > drkm writes:

| [...]

| > | Ces deux points (dé)montrent que l'emploit de `this´ est
| > | soumis aux règles de 3.8/5.

| > ce paragraphe montre

| > que *toute expression* qui désigne l'emplacement de l'objet
| > est utilisation dans la liste d'initialisation

| Ce paragraphe montre

| *comment* certains pointeurs particuliers peuvent être
| utilisés.

pas uniquement ça.


Les conditions que doit remplir un pointeur pour devoir se conformer
aux règles, également énoncées dans ce paragraphe, sp écifiant
*comment* ces pointeurs particuliers peuvent être utilisés.

Quoi d'autre ?

--drkm

4 5 6 7 8