Avant d'attaquer sur le probleme, je vais exposer quelques faits:
Je suis en train de développer une UI pour un jeu d'echecs, qui utilise
le framework wxwidgets. En gros, ce jeu est constitué d'un controlleur
principal, puis de plusieurs moteurs/controlleurs en arriere plan, dont un
moteur réseau. A savoir également qu'une CLI est intégrée.
J'ai donc un problème lorsque j'attend des données provenant du réseau:
l'appel à recv() est bloquant, ce qui provoque un arret du
rafraichissement du programme.
J'ai donc envisagé une solution, qui consiste à "implémenter une
interface" (ie hériter d'une classe avec des méthodes virtuelles).
Bien évidemment, mes UI/CLI hériteraient de cette interface, qui le
forcerait à implémenter une méthode 'refresh()', dont le nom veut tout
dire. De cette maniere, je pourrai faire des appels non bloquants à
recv(), en bouclant tant que rien n'arrive, et en rafraichissant
l'interface à chaque tour de boucle.
Je me retrouve donc avec une UI contenant cette methode virtuelle, la CLI
qui fait de même, et une classe (l'interface) qui aura la méthode
virtuelle pure.
Nous avons donc:
- La classe IUI qui correspondra à l'interface à implémenter.
- La classe de l'UI sera appelée ChessFrame, et heritera de wxFrame,
ainsi que de IUI.
- La classe de la CLI qui sera appelée CLI :p, et héritera également de
IUI.
Je passerai donc, si nécessaire, un pointeur sur un objet de type IUI a
un controlleur, qui appellera la methode refresh() quand il le faudra.
Jusque là, rien de spécial.
Mais je viens de la coder, et bizarrement, lorsque j'effectue les appels,
j'ai l'impression qu'aucune méthode n'est réellement appelée: j'ai mit
un message de trace dans chacune d'elles, de manière à savoir si l'appel
était le bon, mais rien ne s'affiche.
Le code de l'application fait pour le moment a peu pres 6000 lignes, et
j'aurai du mal à tout paster ici.
Cependant, je met quelques morceaux de code qui pourraient être
succeptibles d'éclairer mes propos (certaines portions seront surement
snippées pour ne pas prendre trop de place):
/* Controlleur.cpp */
/***********************************************************/
cout << "Call... ";
/* this->_UI est declaree de type IUI,
* mais correspond a une instance de ChessFrame
*/
this->_UI->refresh();
cout << "Called..." << endl;
/***********************************************************/
Bah je me fais mes casts a l'ancienne, à la C (IUI *), (ChessFrame *)... Cela poste t'il un probleme en C++ ?
Cele revient à faire un reinterpret_cast qui ne permet pas de discerner l'intention de l'auteur (et qui a un comportement indédini).
?? écrire IUI* ui = (IUI*) truc; ne permet pas de "distinguer l'intention" de caster le pointer 'truc' en IUI*; là aussi c'est "moins lisible" (c)(r)(tm) ?
Qu'est-ce que tu essaies à dire là ? Les casts à la C ont plusieurs significations, selon le cas, et ce n'est pas toujours évident laquelle s'applique. Comme j'ai dit par ailleurs, j'ai même eu le cas où une modification ailleurs en a changé la signification.
la surcharge faite ainsi à un comportement *très* défini,
Le comportement est bien défini, mais il dépend de la contexte d'une façon pas du tout évident. Et ici, utiliser le résultat d'un reinterpret_cast a bien un comportement indéfini, même si le cast ne l'a pas.
il mappe le ptr sur la TMV de la classe IUI; c'est le premier appel où un déréférencement quelconque du pointeur qui peut avoir un comportement indéfini ...
C'est quoi la TMV ?
Utiliser les casts C++ permet de rendre explicite ce que l'on cherche à faire.
ils doivent être privilégiés (au dela de l'"intention") dans tous les cas (sauf où c'est impossible, passage par void* par exemple).
Comment, c'est impossible lors d'un passage par void* ? Je m'en sert tout le temps quand j'ai à faire avec les interfaces Posix, par exemple.
mais il est encore plus propre de s'en passer complètement; l'upcast traduit souvent une faiblesse (une mauvaise définition) de la classe de base; lui ajouter la virtuelle pure adéquate évitera un upcast.
Seulement que dans ce cas-ci, il n'a pas de contrôle sur les classes de base.
C'est un cas fréquent dans les GUI, ou d'autres systèmes qui génèrent des évenemments. C'est que la GUI, lui, ne connaît pas ton application, et est donc obligée à maintenir des pointeurs à des types qu'il connaît.
dans le cas d'un héritage multiple, l'héritage virtuel peut être employé si indispensable;
Mais ce n'est évidemment pas le cas ici.
l'erreur plus classique est encore lié au modèle, un bout de code recevant une référence parent "d'une des branches d'héritage" ne devrait pas avoir à invoquer des méthodes de l'autre branche (ou alors il vaut mieux lui transmettre une référence de la classe noeud de l'héritage).
C'est un beau principe. Dans le pratique, quand on travaille avec deux logiciels tiers, on n'a pas toujours le choix.
-- 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
Sylvain wrote:
Arnaud Meurgues wrote on 09/03/2006 13:03:
BOUCNIAUX Benjamin wrote:
Bah je me fais mes casts a l'ancienne, à la C (IUI *),
(ChessFrame *)... Cela poste t'il un probleme en C++ ?
Cele revient à faire un reinterpret_cast qui ne permet pas
de discerner l'intention de l'auteur (et qui a un
comportement indédini).
?? écrire IUI* ui = (IUI*) truc; ne permet pas de "distinguer
l'intention" de caster le pointer 'truc' en IUI*; là aussi
c'est "moins lisible" (c)(r)(tm) ?
Qu'est-ce que tu essaies à dire là ? Les casts à la C ont
plusieurs significations, selon le cas, et ce n'est pas toujours
évident laquelle s'applique. Comme j'ai dit par ailleurs, j'ai
même eu le cas où une modification ailleurs en a changé la
signification.
la surcharge faite ainsi à un comportement *très* défini,
Le comportement est bien défini, mais il dépend de la contexte
d'une façon pas du tout évident. Et ici, utiliser le résultat
d'un reinterpret_cast a bien un comportement indéfini, même si
le cast ne l'a pas.
il mappe le ptr sur la TMV de la classe IUI; c'est le premier
appel où un déréférencement quelconque du pointeur qui peut
avoir un comportement indéfini ...
C'est quoi la TMV ?
Utiliser les casts C++ permet de rendre explicite ce que
l'on cherche à faire.
ils doivent être privilégiés (au dela de l'"intention") dans
tous les cas (sauf où c'est impossible, passage par void* par
exemple).
Comment, c'est impossible lors d'un passage par void* ? Je m'en
sert tout le temps quand j'ai à faire avec les interfaces Posix,
par exemple.
mais il est encore plus propre de s'en passer complètement;
l'upcast traduit souvent une faiblesse (une mauvaise
définition) de la classe de base; lui ajouter la virtuelle
pure adéquate évitera un upcast.
Seulement que dans ce cas-ci, il n'a pas de contrôle sur les
classes de base.
C'est un cas fréquent dans les GUI, ou d'autres systèmes qui
génèrent des évenemments. C'est que la GUI, lui, ne connaît pas
ton application, et est donc obligée à maintenir des pointeurs à
des types qu'il connaît.
dans le cas d'un héritage multiple, l'héritage virtuel peut
être employé si indispensable;
Mais ce n'est évidemment pas le cas ici.
l'erreur plus classique est encore lié au modèle, un bout de
code recevant une référence parent "d'une des branches
d'héritage" ne devrait pas avoir à invoquer des méthodes de
l'autre branche (ou alors il vaut mieux lui transmettre une
référence de la classe noeud de l'héritage).
C'est un beau principe. Dans le pratique, quand on travaille
avec deux logiciels tiers, on n'a pas toujours le choix.
--
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
Bah je me fais mes casts a l'ancienne, à la C (IUI *), (ChessFrame *)... Cela poste t'il un probleme en C++ ?
Cele revient à faire un reinterpret_cast qui ne permet pas de discerner l'intention de l'auteur (et qui a un comportement indédini).
?? écrire IUI* ui = (IUI*) truc; ne permet pas de "distinguer l'intention" de caster le pointer 'truc' en IUI*; là aussi c'est "moins lisible" (c)(r)(tm) ?
Qu'est-ce que tu essaies à dire là ? Les casts à la C ont plusieurs significations, selon le cas, et ce n'est pas toujours évident laquelle s'applique. Comme j'ai dit par ailleurs, j'ai même eu le cas où une modification ailleurs en a changé la signification.
la surcharge faite ainsi à un comportement *très* défini,
Le comportement est bien défini, mais il dépend de la contexte d'une façon pas du tout évident. Et ici, utiliser le résultat d'un reinterpret_cast a bien un comportement indéfini, même si le cast ne l'a pas.
il mappe le ptr sur la TMV de la classe IUI; c'est le premier appel où un déréférencement quelconque du pointeur qui peut avoir un comportement indéfini ...
C'est quoi la TMV ?
Utiliser les casts C++ permet de rendre explicite ce que l'on cherche à faire.
ils doivent être privilégiés (au dela de l'"intention") dans tous les cas (sauf où c'est impossible, passage par void* par exemple).
Comment, c'est impossible lors d'un passage par void* ? Je m'en sert tout le temps quand j'ai à faire avec les interfaces Posix, par exemple.
mais il est encore plus propre de s'en passer complètement; l'upcast traduit souvent une faiblesse (une mauvaise définition) de la classe de base; lui ajouter la virtuelle pure adéquate évitera un upcast.
Seulement que dans ce cas-ci, il n'a pas de contrôle sur les classes de base.
C'est un cas fréquent dans les GUI, ou d'autres systèmes qui génèrent des évenemments. C'est que la GUI, lui, ne connaît pas ton application, et est donc obligée à maintenir des pointeurs à des types qu'il connaît.
dans le cas d'un héritage multiple, l'héritage virtuel peut être employé si indispensable;
Mais ce n'est évidemment pas le cas ici.
l'erreur plus classique est encore lié au modèle, un bout de code recevant une référence parent "d'une des branches d'héritage" ne devrait pas avoir à invoquer des méthodes de l'autre branche (ou alors il vaut mieux lui transmettre une référence de la classe noeud de l'héritage).
C'est un beau principe. Dans le pratique, quand on travaille avec deux logiciels tiers, on n'a pas toujours le choix.
-- 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
Sylvain
Arnaud Meurgues wrote on 10/03/2006 09:10:
Ben non. Il peut très bien, sur du code non trivial, penser faire un un static cast de style down cast qui devient en fait un reinterpret_cast parce que les types ne peuvent se caster.
oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Lorsque je lis
IUI* ui = (IUI*)truc;
Je ne sais absolument pas si le truc en question est supposé pouvoir se caster ou si c'est pour faire un mapping sale à la C.
si tu regardes sa définition postée, tu ne trouves aucun opérateur de surcharge, de plus "truc" est un pointeur et AFAIK un opérateur de cast s'applique à une référence, donc, oui, « c'est du sale C » qui marchera très bien en héritage simple et peut partir dans le décor pour un héritage multiple.
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...]
vraiment ?
Sylvain.
Arnaud Meurgues wrote on 10/03/2006 09:10:
Ben non. Il peut très bien, sur du code non trivial, penser faire un un
static cast de style down cast qui devient en fait un reinterpret_cast
parce que les types ne peuvent se caster.
oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Lorsque je lis
IUI* ui = (IUI*)truc;
Je ne sais absolument pas si le truc en question est supposé pouvoir se
caster ou si c'est pour faire un mapping sale à la C.
si tu regardes sa définition postée, tu ne trouves aucun opérateur de
surcharge, de plus "truc" est un pointeur et AFAIK un opérateur de cast
s'applique à une référence, donc, oui, « c'est du sale C » qui marchera
très bien en héritage simple et peut partir dans le décor pour un
héritage multiple.
Mais si le pointeur n'est jamais déréférencé, je ne suis pas
certain que le cast ait le moindre sens. [...]
Ben non. Il peut très bien, sur du code non trivial, penser faire un un static cast de style down cast qui devient en fait un reinterpret_cast parce que les types ne peuvent se caster.
oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Lorsque je lis
IUI* ui = (IUI*)truc;
Je ne sais absolument pas si le truc en question est supposé pouvoir se caster ou si c'est pour faire un mapping sale à la C.
si tu regardes sa définition postée, tu ne trouves aucun opérateur de surcharge, de plus "truc" est un pointeur et AFAIK un opérateur de cast s'applique à une référence, donc, oui, « c'est du sale C » qui marchera très bien en héritage simple et peut partir dans le décor pour un héritage multiple.
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...]
vraiment ?
Sylvain.
Arnaud Meurgues
Sylvain wrote:
Ben non. Il peut très bien, sur du code non trivial, penser faire un un static cast de style down cast qui devient en fait un reinterpret_cast parce que les types ne peuvent se caster. oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Voir le message de James.
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...] vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose sans déréférencement ultérieur. Vous avez un exemple ?
-- Arnaud
Sylvain wrote:
Ben non. Il peut très bien, sur du code non trivial, penser faire un un
static cast de style down cast qui devient en fait un reinterpret_cast
parce que les types ne peuvent se caster.
oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Voir le message de James.
Mais si le pointeur n'est jamais déréférencé, je ne suis pas
certain que le cast ait le moindre sens. [...]
vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose
sans déréférencement ultérieur. Vous avez un exemple ?
Ben non. Il peut très bien, sur du code non trivial, penser faire un un static cast de style down cast qui devient en fait un reinterpret_cast parce que les types ne peuvent se caster. oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Voir le message de James.
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...] vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose sans déréférencement ultérieur. Vous avez un exemple ?
-- Arnaud
Gabriel Dos Reis
Sylvain writes:
| Arnaud Meurgues wrote on 10/03/2006 09:10: | > Ben non. Il peut très bien, sur du code non trivial, penser faire un | > un | > static cast de style down cast qui devient en fait un reinterpret_cast | > parce que les types ne peuvent se caster. | | oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que | l'on peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis | pas bien.
moi non plus, mais qui parle de stroumpf?
-- Gaby
Sylvain <noSpam@mail.net> writes:
| Arnaud Meurgues wrote on 10/03/2006 09:10:
| > Ben non. Il peut très bien, sur du code non trivial, penser faire un
| > un
| > static cast de style down cast qui devient en fait un reinterpret_cast
| > parce que les types ne peuvent se caster.
|
| oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que
| l'on peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis
| pas bien.
| Arnaud Meurgues wrote on 10/03/2006 09:10: | > Ben non. Il peut très bien, sur du code non trivial, penser faire un | > un | > static cast de style down cast qui devient en fait un reinterpret_cast | > parce que les types ne peuvent se caster. | | oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que | l'on peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis | pas bien.
moi non plus, mais qui parle de stroumpf?
-- Gaby
Sylvain
Arnaud Meurgues wrote on 10/03/2006 22:55:
Sylvain wrote:
Ben non. Il peut très bien, sur du code non trivial, penser faire un un static cast de style down cast qui devient en fait un reinterpret_cast parce que les types ne peuvent se caster. oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Voir le message de James.
ah bon, comprendre Arnaud dans le texte (1) présuppose lire James qui postera 1h06 plus tard, c'est limpide; au delà le point (plus illustré) de James illustre mieux, en effet, les "bonnes écritures".
(1):
Il peut très bien, sur du code non trivial, le code est ici présent dans le premier post et *est* trivial
penser faire un donc on conjecture sur ce qu'il aura peut être pensé faire
("on" fait du C++ ou de la voyance ?)
un static cast de style down cast donc un truc qui ne sert à rien
(pour rappel, Cf Bjarne St., The C++ Prog. Lang. § 6.2.7)
qui devient en fait un reinterpret_cast non qui aurait du être codé *explicitement* "reinterpret" (ou mieux
"dynamic"), le compilo ne risque pas d'insérer ce statement tout seul
parce que les types ne peuvent se caster. cela n'empêche pas le cast "à la C" à forcer le compilateur à considérer
l'adresse argument comme un pointeur valide et donc autoriser l'accès à des données ou fonctions membres de sa classe (avec les risques déjà décrits).
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...] vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose sans déréférencement ultérieur. Vous avez un exemple ?
excuse-moi, c'était de l'ironie a) rappeller que "ce qui ne sert à rien", "ne sert à rien" ne m'avait pas paru si indispensable, b) je n'ai pas dit qu'il fallait caster un pointeur pour ne plus-jamais-surtout le déréférencer, mais au contraire que la bombe se déclenchera sur *ce* déréférencement (qui existe donc).
Sylvain.
Arnaud Meurgues wrote on 10/03/2006 22:55:
Sylvain wrote:
Ben non. Il peut très bien, sur du code non trivial, penser faire un un
static cast de style down cast qui devient en fait un reinterpret_cast
parce que les types ne peuvent se caster.
oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Voir le message de James.
ah bon, comprendre Arnaud dans le texte (1) présuppose lire James qui
postera 1h06 plus tard, c'est limpide; au delà le point (plus illustré)
de James illustre mieux, en effet, les "bonnes écritures".
(1):
Il peut très bien, sur du code non trivial,
le code est ici présent dans le premier post et *est* trivial
penser faire un
donc on conjecture sur ce qu'il aura peut être pensé faire
("on" fait du C++ ou de la voyance ?)
un static cast de style down cast
donc un truc qui ne sert à rien
(pour rappel, Cf Bjarne St., The C++ Prog. Lang. § 6.2.7)
qui devient en fait un reinterpret_cast
non qui aurait du être codé *explicitement* "reinterpret" (ou mieux
"dynamic"), le compilo ne risque pas d'insérer ce statement tout seul
parce que les types ne peuvent se caster.
cela n'empêche pas le cast "à la C" à forcer le compilateur à considérer
l'adresse argument comme un pointeur valide et donc autoriser l'accès à
des données ou fonctions membres de sa classe (avec les risques déjà
décrits).
Mais si le pointeur n'est jamais déréférencé, je ne suis pas
certain que le cast ait le moindre sens. [...]
vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose
sans déréférencement ultérieur. Vous avez un exemple ?
excuse-moi, c'était de l'ironie
a) rappeller que "ce qui ne sert à rien", "ne sert à rien" ne m'avait
pas paru si indispensable,
b) je n'ai pas dit qu'il fallait caster un pointeur pour ne
plus-jamais-surtout le déréférencer, mais au contraire que la bombe se
déclenchera sur *ce* déréférencement (qui existe donc).
Ben non. Il peut très bien, sur du code non trivial, penser faire un un static cast de style down cast qui devient en fait un reinterpret_cast parce que les types ne peuvent se caster. oui ?! t'as pas un exemple ? parce que "stroumpfer le stroumpf que l'on
peut pas stroumpfer sauf s'il se stroumpfe tout seul" je saisis pas bien.
Voir le message de James.
ah bon, comprendre Arnaud dans le texte (1) présuppose lire James qui postera 1h06 plus tard, c'est limpide; au delà le point (plus illustré) de James illustre mieux, en effet, les "bonnes écritures".
(1):
Il peut très bien, sur du code non trivial, le code est ici présent dans le premier post et *est* trivial
penser faire un donc on conjecture sur ce qu'il aura peut être pensé faire
("on" fait du C++ ou de la voyance ?)
un static cast de style down cast donc un truc qui ne sert à rien
(pour rappel, Cf Bjarne St., The C++ Prog. Lang. § 6.2.7)
qui devient en fait un reinterpret_cast non qui aurait du être codé *explicitement* "reinterpret" (ou mieux
"dynamic"), le compilo ne risque pas d'insérer ce statement tout seul
parce que les types ne peuvent se caster. cela n'empêche pas le cast "à la C" à forcer le compilateur à considérer
l'adresse argument comme un pointeur valide et donc autoriser l'accès à des données ou fonctions membres de sa classe (avec les risques déjà décrits).
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...] vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose sans déréférencement ultérieur. Vous avez un exemple ?
excuse-moi, c'était de l'ironie a) rappeller que "ce qui ne sert à rien", "ne sert à rien" ne m'avait pas paru si indispensable, b) je n'ai pas dit qu'il fallait caster un pointeur pour ne plus-jamais-surtout le déréférencer, mais au contraire que la bombe se déclenchera sur *ce* déréférencement (qui existe donc).
Sylvain.
Sylvain
Arnaud Meurgues wrote on 10/03/2006 22:55:
Mais si le pointeur n'est jamais déréférencé, je ne suis pas certain que le cast ait le moindre sens. [...] vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose sans déréférencement ultérieur. Vous avez un exemple ?
désolé c'était de l'ironie; je n'ai pas dit qu'il fallait caster un
pointeur pour ne pas le déréférencer, mais au contraire que la bombe se déclenchera sur ce déréférencement (qui existe donc).
Sylvain.
Arnaud Meurgues wrote on 10/03/2006 22:55:
Mais si le pointeur n'est jamais déréférencé, je ne suis pas
certain que le cast ait le moindre sens. [...]
vraiment ?
Là, j'ai un peu de mal à trouver un cas où le cast sert à quelque chose
sans déréférencement ultérieur. Vous avez un exemple ?
désolé c'était de l'ironie; je n'ai pas dit qu'il fallait caster un
pointeur pour ne pas le déréférencer, mais au contraire que la bombe se
déclenchera sur ce déréférencement (qui existe donc).