Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Appel d'une methode a partir d'un pointeur nul

28 réponses
Avatar
Olivier Miakinen
Bonjour,


Je voudrais savoir si ceci est légal :

class UneClasse
{
public:
void UneMethode();
/* plus d'autres méthodes */
}

void UneClasse::UneMethode()
{
if (this) {
/* faire des choses */
}
/* sinon ne rien faire */
}

et quelque part ailleurs :

UneClasse *uneInstance = NULL;
uneInstance->UneMethode();


Je viens de tomber sur un code qui fait quelque chose comme ça
(enfin... si je ne me suis pas trompé en recopiant et en changeant
les identifiants), et je me demande si cette façon d'appeler une
méthode en déréférençant un pointeur nul est portable. Je précise
que cela compile et s'exécute sans problème apparent avec Visual C++.


Cordialement,
--
Olivier Miakinen

10 réponses

1 2 3
Avatar
Pierre Barbier de Reuille
Olivier Miakinen wrote:
Bonjour,


Je voudrais savoir si ceci est légal :

class UneClasse
{
public:
void UneMethode();
/* plus d'autres méthodes */
}

void UneClasse::UneMethode()
{
if (this) {
/* faire des choses */
}
/* sinon ne rien faire */
}

et quelque part ailleurs :

UneClasse *uneInstance = NULL;
uneInstance->UneMethode();


Je viens de tomber sur un code qui fait quelque chose comme ça
(enfin... si je ne me suis pas trompé en recopiant et en changeant
les identifiants), et je me demande si cette façon d'appeler une
méthode en déréférençant un pointeur nul est portable. Je précise
que cela compile et s'exécute sans problème apparent avec Visual C++.


Cordialement,


Je dirais que tant que la méthode n'est pas virtuelle pourquoi pas ...
Après tout une méthode non-virtuelle n'est rien d'autre qu'une fonction
avec un argument implicite : this. Après, c'est quand même bizarre sur
le plan de la logique !!!

Pierre

Avatar
Manuel Zaccaria
Olivier Miakinen a écrit:

Bonjour,


Je voudrais savoir si ceci est légal :


[snip code illégal]

Je viens de tomber sur un code qui fait quelque chose comme ça
(enfin... si je ne me suis pas trompé en recopiant et en changeant
les identifiants), et je me demande si cette façon d'appeler une
méthode en déréférençant un pointeur nul est portable. Je précise
que cela compile et s'exécute sans problème apparent avec Visual C++.


D'après la norme, toute tentative de déréférencer un pointeur
est un comportement indéfini aka "undefined behavior".
A mettre à la corbeille en ce qui me concerne.

Manuel

Avatar
Manuel Zaccaria
J'ai écrit:

D'après la norme, toute tentative de déréférencer un pointeur
...un pointeur nul


est un comportement indéfini aka "undefined behavior".


Manuel

Avatar
Sylvain
Olivier Miakinen wrote on 08/09/2006 18:59:

class UneClasse {
public:
void UneMethode();
}
UneClasse *uneInstance = NULL;
uneInstance->UneMethode();

cela compile et s'exécute sans problème apparent avec Visual C++.


quelle version ? quel mode d'exécution ? ...
98, 2003, 2005 plante une bombe pour l'accès à un pointeur null

... sauf pour 98 si la méthode est statique, c'est ici une erreur du
compilo qui accepte le "uneInstance->" ou "uneInstance." alors que seul
"UneClasse::" devrait être valide.

Sylvain.

Avatar
Sylvain
Sylvain wrote on 08/09/2006 23:19:

.... sauf pour 98 si la méthode est statique


pas seulement en effet, il push this et appelle la méthode qui bombera
que si cette adresse bidon est utilisée pour accéder à une donnée membre
(et donc jamais si la méthode est fonctionnellement statique).

il ne détecte immédiatement l'accès invalide que si l'appel est virtuel
(of course), pas très propre ça.

Sylvain.

Avatar
Olivier Miakinen

D'après la norme, toute tentative de déréférencer un pointeur
[nul] est un comportement indéfini aka "undefined behavior".
A mettre à la corbeille en ce qui me concerne.


Merci à toi, ainsi qu'à Pierre et Sylvain. Je vais tâcher de faire la
chasse à ces utilisations foireuses, donc. Souhaitez-moi bonne chance
pour les trouver toutes !

Avatar
Sylvain
Sylvain wrote on 08/09/2006 23:19:

class UneClasse {
public:
void UneMethode();
}
UneClasse *uneInstance = NULL;
uneInstance->UneMethode();

cela compile et s'exécute sans problème apparent avec Visual C++.



comment se comportent d'autres compilo ?

VC98 ne fait aucun contrôle sur ce que contient l'adresse prétendue de
la référence, c'est le standard ?

on peut (pour une struct sans vtable) définir une instance utilisée
comme valide via par exemple:

class UneClasse {
public:
int a;
void UneMethode();
};

void UneClasse::UneMethode()
{
if (this)
a = 1;
}

int main(){
int area;
UneClasse* uneInstance = (UneClasse*) &area;
uneInstance->UneMethode();
}

cette façon de "créer" une instance à la main est originale, j'utilise
plus souvent "l'autre sens" :

class UneAutre {
private:
int pasToucher;
};

int main()
{
UneClasse uneInstance;
int& benSi = *(int*) &uneInstance;
benSi = 1;
}

le mapping étant constant, il n'y avait pas de raison que cela ne marche
pas dans l'autre sens ... sauf à du code de contrôle supplémentaire.

Sylvain.


Avatar
Sylvain
Olivier Miakinen wrote on 09/09/2006 00:11:
D'après la norme, toute tentative de déréférencer un pointeur
[nul] est un comportement indéfini aka "undefined behavior".
A mettre à la corbeille en ce qui me concerne.


Merci à toi, ainsi qu'à Pierre et Sylvain. Je vais tâcher de faire la
chasse à ces utilisations foireuses, donc. Souhaitez-moi bonne chance
pour les trouver toutes !


mets une définition de virtuelle (un destructeur virtuel par exemple)
dans tes classes ça bombera direct; bon si tu en as 5000 ...

Sylvain.


Avatar
Fabien LE LEZ
On Sat, 09 Sep 2006 00:11:57 +0200, Olivier Miakinen
<om+:

Je vais tâcher de faire la
chasse à ces utilisations foireuses, donc.


Une méthode possible (pour vérification à l'exécution) est de
remplacer

if (this)

par

assert (this);

Avatar
Olivier Miakinen

Merci à toi, ainsi qu'à Pierre et Sylvain. Je vais tâcher de faire la
chasse à ces utilisations foireuses, donc. Souhaitez-moi bonne chance
pour les trouver toutes !




Le 09/09/2006 00:21, Sylvain m'a répondu :

mets une définition de virtuelle (un destructeur virtuel par exemple)
dans tes classes ça bombera direct; bon si tu en as 5000 ...


Il est bien possible qu'il y ait 5 000 classes, oui. En tout cas
plusieurs centaines, et peut-être quelques milliers.


Le 09/09/2006 00:43, Fabien LE LEZ m'a répondu :

Une méthode possible (pour vérification à l'exécution) est de
remplacer
if (this)
par
assert (this);


Je vais déjà commencer par faire un grep sur "this", avec un peu de
chance il n'y en aura pas tant que ça.


Encore merci !


1 2 3