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

1 2 3 4 5
Avatar
darkman_spam
wrote in message
news:...

drkm wrote in message
news:...

writes:

drkm wrote in message
news:...

Je n'ai cependant pas réussi à trouver un passage clair sur
l'appartenance ou non du `ctor-initializer´ au corps de son
constructeur. S'il devait s'avérer qu'il n'y appartient pas,
il ne serait alors pas possible d'y utiliser `this´, non ?


Ce qui suggèrerait que l'utilisation de this dans la liste
d'initialisation serait illégale.


Oui. Si le `ctor-initializer´ ne fait pas partie du corps du
constructeur.


Ce que je crains, c'est que c'est parfois oui, parfois non, selon
l'auteur exact du passage.


Ce qui est embêtant.

Tous les compilateurs le permettent, et je suis assez sûr que
c'était l'intention du comité de le permettra.


C'est ce que j'imagine. Mais ce ne serait pas, je pense, le
premier exemple de contradiction entre l'intention du comité et sa
rédaction dans la norme ...


Certes. C'est ce qui arrive quand on veut faire trop, trop vite.


Ce dont le JTC1/SC22/WG21 n'a pas le monopole :-).

D'autant que je ne vois pas de raison pour un compilateur de
connaître la valeur de `this´ dans le corps du constructeur (je
veux dire après l'accolade ouvrante) et non dans la liste
d'initialistion.


S'il ne connaît pas this dans la liste d'initialisation, comment
fait-il à passer le this aux constructeurs des sous-objets ?


Je vois même maintenant une raison pour qu'il la connaisse dans la
liste d'initialisation :-).

Dans ce cas-ci, l'idiome est assez courant. Assez pour que je
crois Microsoft a eu tort d'émettre un avertissment, même si ça
part d'un bon sentiment.


Du moins, de l'émettre sans options particulières. Je le
verrais bien dans un mode « full warnings ». Un peu comme
`-Weffc++´ peut avec GCC nous submerger d'avertissements inutiles,
ou en émettre de très pertinents.


Je ne sais pas. Dans la doute, je crois que mettre un maximum
d'avertissements par défaut, ce n'est peut-être pas une mauvaise
politique. Après tout, le programmeur qui sait ce qu'il fait sait
qu'il faut lire la documentation, et spécifier exactement des
avertissements dont il a besoin.


Comme tu le dis, « le programmeur qui sait ce qu'il fait sait qu'il
faut lire la documentation, et spécifier exactement des avertissements
dont il a besoin ». De l'autre côté, celui du programmeur qui ne sait
pas ce qu'il fait (je pense surtout aux débutants), les diagnostiques
sont souvent du chinois pour le néophyte et j'ai vu beaucoup d'élèves,
face à d'innombrables avertissements, hausser les bras : « Ce ne sont
que des warnings ». Peut-être que s'ils n'en recevaient que
quelques-uns seraient-ils plus enclins à s'y attarder.

Mais évidemment, si on a un programmeur qui ne sait pas ce qu'il
fait, avertissements ou pas, on va directement dans le mur.

Mais j'aimerais savoir ce qu'il en est pour l'appartenance du
`ctor-initializer´ au corps du constructeur. Quelqu'un a-t-il une
piste ?


Il faudra peut-être démander dans comp.std.c++.


Ok. Mon serveur de news a pour l'instant de gros problèmes. Je
viens de leur téléphoner, ils « sont au courant et s'occupent de tout,
au plus vite » ... Je poste dès que possible.

--drkm




Avatar
James Kanze
Gabriel Dos Reis writes:

|> writes:

|> | > Je n'ai cependant pas réussi à trouver un passage
|> | > clair sur l'appartenance ou non du `ctor-initializer´ au
|> | > corps de son constructeur. S'il devait s'avérer qu'il n'y
|> | > appartient pas, il ne serait alors pas possible d'y utiliser
|> | > `this´, non ?

|> | Ce qui suggèrerait que l'utilisation de this dans la liste
|> | d'initialisation serait illégale. Tous les compilateurs le
|> | permettent, et je suis assez sûr que c'était l'intention
|> | du comité de le permettra.

|> L'utilisation de « this » dans le ctor-initializer est
|> tout ce qu'il y a de plus valide. Voir 3.8/5 -- que je n'ai pas
|> le temps de citer, mais ce n'est pas un problème puisque nombre
|> d'intervenants dans ce thread semblent disposer d'un exemplaire de
|> la norme.

Mais ce n'était pas là le problème. On sait qu'il peut
exister des pointeurs à l'objet avant que l'objet soit construit,
et qu'il y a des limitations à ce qu'on peut faire avec de tels
pointeurs.

Mais la réponse voulue se trouve bien dans 5.1/3, qui dit
explicitement que this peut servir dans la liste d'initialisation d'un
constructeur. (J'aurais dû régarder avant de répondre -- le
texte cité avant dans le thread parlait uniquement de l'utilisation
de this dans le corps d'une fonction, ce qui aurait exclu les listes
d'initialisation.)

--
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
James Kanze
Gabriel Dos Reis writes:

|> James Kanze writes:

|> | Gabriel Dos Reis writes:
|> | |> L'utilisation de « this » dans le ctor-initializer
|> | |> est tout ce qu'il y a de plus valide. Voir 3.8/5 -- que je
|> | |> n'ai pas le temps de citer, mais ce n'est pas un problème
|> | |> puisque nombre d'intervenants dans ce thread semblent
|> | |> disposer d'un exemplaire de la norme.

|> | Mais ce n'était pas là le problème.

|> Ah bon ?

|> | On sait qu'il peut exister des pointeurs à l'objet avant que
|> | l'objet soit construit, et qu'il y a des limitations à ce
|> | qu'on peut faire avec de tels pointeurs.

|> Le point que tu n'as pas saisi est qu'il peut être utilisé
|> dans la liste d'initialisation. Ce qui répond à la question
|> posée.

Manifestement, tu n'as pas suivi le fil depuis son début.

--
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
drkm
Gabriel Dos Reis writes:

James Kanze writes:

| Mais ce n'était pas là le problème.

Ah bon ?


Ah bon ?

| On sait qu'il peut exister des pointeurs à l'objet avant que
| l'objet soit construit, et qu'il y a des limitations à ce qu'on
| peut faire avec de tels pointeurs.

Le point que tu n'as pas saisi est qu'il peut être utilisé dans la
liste d'initialisation.


Et cela est dit dans 3.8/5 ?

Ce qui répond à la question posée.


Ce qui réponderait à la question posée.

--drkm

Avatar
drkm
James Kanze writes:

Mais la réponse voulue se trouve bien dans 5.1/3


Merci, c'est là tout ce que je cherchais.

--drkm

Avatar
Gabriel Dos Reis
drkm writes:

| Gabriel Dos Reis writes:
|
| > drkm writes:
|
| > | > Le point que tu n'as pas saisi est qu'il peut être utilisé dans la
| > | > liste d'initialisation.
|
| > | Et cela est dit dans 3.8/5 ?
|
| > oui.
|
| Pourrais-tu citer le passage précis, s'il te plaît ? Je n'arrive
| pas à voir où il est dit, dans 3.8/5, que `this´ peut être utilisé
| dans la liste d'initialisation.

La phrase clé est

Before the lifetime of an object started but after the storage which
the object has been allocated or, after the lifetime or an object
has ended and before the storage which the object occupied is reused
or released, any pointer that refers to the storage location where
the object will be or was located *may be used* but only in limited
ways. [...]

1) "this" désigne où va se trouver l'objet ;
2) le constructeur est appelé après allocation de mémoire et la durée
de vie d'un objet n'a pas commencé avant que le constructeur ait
fini de s'éxécuter.

-- Gaby
Avatar
Gabriel Dos Reis
drkm writes:

| Gabriel Dos Reis writes:
|
| > drkm writes:
|
| > | Gabriel Dos Reis writes:
|
| > | > drkm writes:
|
| > | > | > Le point que tu n'as pas saisi est qu'il peut être utilisé
| > | > | > dans la liste d'initialisation.
|
| > | > | Et cela est dit dans 3.8/5 ?
|
| > | > oui.
|
| > | Pourrais-tu citer le passage précis, s'il te plaît ? Je n'arrive
| > | pas à voir où il est dit, dans 3.8/5, que `this´ peut être utilisé
| > | dans la liste d'initialisation.
|
| > La phrase clé est
|
| > Before the lifetime of an object started but after the storage
| > which the object has been allocated or, after the lifetime or an
| > object has ended and before the storage which the object occupied
| > is reused or released, any pointer that refers to the storage
| > location where the object will be or was located *may be used* but
| > only in limited ways. [...]
|
| > 1) "this" désigne où va se trouver l'objet ;
| > 2) le constructeur est appelé après allocation de mémoire et la
| > durée de vie d'un objet n'a pas commencé avant que le
| > constructeur ait fini de s'éxécuter.
|
| Non, je demandais où tu voyais, dans 3.8/5, que `this´ est
| utilisable dans la liste d'initialisation.

C'est ce que je viens de te montrer.

-- Gaby
Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| Gabriel Dos Reis writes:

| > drkm writes:

| > | > Le point que tu n'as pas saisi est qu'il peut être utilisé
| > | > dans la liste d'initialisation.

| > | Et cela est dit dans 3.8/5 ?

| > oui.

| Pourrais-tu citer le passage précis, s'il te plaît ? Je n'arrive
| pas à voir où il est dit, dans 3.8/5, que `this´ peut être utilisé
| dans la liste d'initialisation.

La phrase clé est

Before the lifetime of an object started but after the storage
which the object has been allocated or, after the lifetime or an
object has ended and before the storage which the object occupied
is reused or released, any pointer that refers to the storage
location where the object will be or was located *may be used* but
only in limited ways. [...]

1) "this" désigne où va se trouver l'objet ;
2) le constructeur est appelé après allocation de mémoire et la
durée de vie d'un objet n'a pas commencé avant que le
constructeur ait fini de s'éxécuter.


Non, je demandais où tu voyais, dans 3.8/5, que `this´ est
utilisable dans la liste d'initialisation.

--drkm

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

Gabriel Dos Reis writes:
La phrase clé est

Before the lifetime of an object started but after the storage
which the object has been allocated or, after the lifetime or an
object has ended and before the storage which the object occupied
is reused or released, any pointer that refers to the storage
location where the object will be or was located *may be used* but
only in limited ways. [...]

1) "this" désigne où va se trouver l'objet ;
2) le constructeur est appelé après allocation de mémoire et la
durée de vie d'un objet n'a pas commencé avant que le
constructeur ait fini de s'éxécuter.


Non, je demandais où tu voyais, dans 3.8/5, que `this´ est
utilisable dans la liste d'initialisation.


Ce que je comprends ici, c'est que this semble remplir les
critères du paragraphe cité - donc son usage est autorisé
(implicitement).

--

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


Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| Non, je demandais où tu voyais, dans 3.8/5, que `this´ est
| utilisable dans la liste d'initialisation.

C'est ce que je viens de te montrer.


Non.

--drkm

1 2 3 4 5