OVH Cloud OVH Cloud

reference et NULL

13 réponses
Avatar
Amerio
Bonjour,
J'ai toujours considéré qu'il fallait utiliser une référence (&) quand on
voulait garantir à une fonction qu'un paramètre ne pouvait pas être NULL :
void fct( Toto* t) // t peut être NULL, fct doit vérifier
void fct( Toto& t) // t est forcément valide

Hors, en faisant un test, le code suivant ne produit aucune erreur :

struct Toto { ... } ;
int main()
{
Toto t1;
Toto *t0 = 0;
Toto& t = t1; // ok tout va bien
t = *t0; // ca ne plante pas a l'execution !
// si j'utilise t, maintenant, ca plantera ! mais ca ne plante pas à
l'affectation !
}

Donc je peux passer une référence invalide (NULL) à une fonction !
Ou bien mon raisonnement est faux et on a aucune garantie sur les references
?
(testé avec gcc 2.95)

3 réponses

1 2
Avatar
James Kanze
Marc Boyer wrote:
wrote:


Marc Boyer wrote:



In article <41e27eb4$0$19589$, Amerio wrote:




Toto t1;
Toto *t0 = 0;
Toto& t = t1; // ok tout va bien
t = *t0; // ca ne plante pas a l'execution !





[SNIP]


La question est, qu'est-ce qu'il essaie de montrer comme
point. Il commence en parlant de NULL, et qu'on ne peut pas
avoir des références nulle, mais son programme déréférence un
pointeur NULL, ce qui n'a rien à voir avec des références.



Oui et non.
Non dans le sens où ce sont des choses différentes.
Mais oui quand même dans le sens ou je ne serais pas
étonné qu'un compilateur représente en interne un pointeur
et une référence de la même manière, et qu'il optimise
une écriture du genre
Toto &t= *t;
en une copie interne de pointeur à pointeur.


Ça dépend du contexte ; c'est une implémentation possible, même
s'il m'étonnerait un peu pour une variable locale.

Mais je ne vois toujours pas de rapport. Il n'y a pas de Toto &t
= *t dans son programme. Il y a un t qui est bien initialisé,
avec une variable locale. Et puis, on affecte ce t. C-à-d qu'on
affecte la variable locale avec lequel il a été initialisé.

Le problème dans son code n'est pas là. Le problem, c'est avec
le *t0 à droit de l'affectation. Et ça, c'est un problème avec
ou sans une référence à gauche ; t1 = *t0 pose autant de
problèmes.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34




Avatar
Marc Boyer
James Kanze wrote:
Marc Boyer wrote:
wrote:
Oui et non.
Non dans le sens où ce sont des choses différentes.
Mais oui quand même dans le sens ou je ne serais pas
étonné qu'un compilateur représente en interne un pointeur
et une référence de la même manière, et qu'il optimise
une écriture du genre
Toto &t= *t;
en une copie interne de pointeur à pointeur.


Ça dépend du contexte ; c'est une implémentation possible, même
s'il m'étonnerait un peu pour une variable locale.


Oui, en y réflechissant bien oui.

Mais je ne vois toujours pas de rapport. Il n'y a pas de Toto &t
= *t dans son programme. Il y a un t qui est bien initialisé,
avec une variable locale. Et puis, on affecte ce t. C-à-d qu'on
affecte la variable locale avec lequel il a été initialisé.


Tout à fait.

Le problème dans son code n'est pas là. Le problem, c'est avec
le *t0 à droit de l'affectation. Et ça, c'est un problème avec
ou sans une référence à gauche ; t1 = *t0 pose autant de
problèmes.


En fait, je me suis demandé pas mal s'il nous avait posté
exactement le code qu'il avait testé, car comme le tien,
mon compilateur plante dès l'affectation, pas après lors
de l'utilisation comme décrit par l'OP.
Mais comme les réponses données lui faisaient comprendre
son erreur conceptuelle, j'ai pas poussé dans le cas de
l'exemple donné.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
Amerio
En fait, je me suis demandé pas mal s'il nous avait posté
exactement le code qu'il avait testé, car comme le tien,
mon compilateur plante dès l'affectation, pas après lors
de l'utilisation comme décrit par l'OP.


Oui le code que j'avais ecris etait exactement celui testé.
Pour rappel :
struct Toto {} ;
int main()
{
Toto t1;
Toto *t0 = 0;
Toto& t = t1; // ok tout va bien
t = *t0; // ca ne plante pas a l'execution *chez moi*
}

Mais comme les réponses données lui faisaient comprendre
son erreur conceptuelle, j'ai pas poussé dans le cas de
l'exemple donné.


Tout a fait. En fait d'erreur de conception, ca fait parti de tests persos
que j'avais écris pour vérifier un truc sur les pointeurs, puis à force de
faire des trucs à droite à gauche pour comparer l'utilisation pointeur /
référence, j'ai dérivé jusqu'à "la chose" commise plus haut.

1 2