j'ai un petit code qui m'étonne... soit une fonction prenant un void*
en paramètre, lors de son appel, si je lui passe un double*, mon
compilateur dit rien... ok.
soit une fonction retournant un void *, lorsque j'assigne un double*
avec le retour de cette fonction, mon compilateur ne dit rien...
ici donc, pas besoin de caster ni le paramètre (en (void*)), ni le
retour de fonction (en (double*))...
maintenant, on prend les même et on recommence, à la différence près
que mon argument n'est plus un void* mais un void**, et mon retour
n'est plus un void* mais aussi un void **. là plus rien ne passe...
lors de l'appel de la fonction je suis obligé de caster mon double** en
void**, et lors du retour, je suis obligé de caster en double**,
pourquoi ?
pour un exemple plus parlant, considérez le code suivant :
| Gabriel Dos Reis wrote: | > Jean-Marc Bourguet writes: | > | >| Yves ROMAN writes: | >| | >| > > Je ne vois pas pourquoi. La seule contrainte c'est que | >| > > void* est capable de représenter précisément tous les types | >| > > de pointeurs. | >| > | >| > Peut on donc dire, pour tout type de donnée T, que : | >| > sizeof(void *) >= sizeof(T *) ? | >| | >| Ce n'est pas formel mais je ne vois pas de plateforme ou il aurait ete | >| raisonnable que ce ne soit pas le cas. | > | > Je crois qu'il y a des indications dans la norme qu'on peut déduire | > | > sizeof (void*) == sizeof (char*) | | 6.2.5/26 | A pointer to void shall have the same representation and alignment | requirements as a pointer to a character type. | | > && sizeof (void*) >= sizeof (T*) | | Ca, j'ai pas vu.
Tu peux caster T* en void* sans perte d'information.
-- Gaby
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> writes:
| Gabriel Dos Reis wrote:
| > Jean-Marc Bourguet <jm@bourguet.org> writes:
| >
| >| Yves ROMAN <yves.roman@NO.unilog.SPAM.fr> writes:
| >|
| >| > > Je ne vois pas pourquoi. La seule contrainte c'est que
| >| > > void* est capable de représenter précisément tous les types
| >| > > de pointeurs.
| >| >
| >| > Peut on donc dire, pour tout type de donnée T, que :
| >| > sizeof(void *) >= sizeof(T *) ?
| >|
| >| Ce n'est pas formel mais je ne vois pas de plateforme ou il aurait ete
| >| raisonnable que ce ne soit pas le cas.
| >
| > Je crois qu'il y a des indications dans la norme qu'on peut déduire
| >
| > sizeof (void*) == sizeof (char*)
|
| 6.2.5/26
| A pointer to void shall have the same representation and alignment
| requirements as a pointer to a character type.
|
| > && sizeof (void*) >= sizeof (T*)
|
| Ca, j'ai pas vu.
Tu peux caster T* en void* sans perte d'information.
| Gabriel Dos Reis wrote: | > Jean-Marc Bourguet writes: | > | >| Yves ROMAN writes: | >| | >| > > Je ne vois pas pourquoi. La seule contrainte c'est que | >| > > void* est capable de représenter précisément tous les types | >| > > de pointeurs. | >| > | >| > Peut on donc dire, pour tout type de donnée T, que : | >| > sizeof(void *) >= sizeof(T *) ? | >| | >| Ce n'est pas formel mais je ne vois pas de plateforme ou il aurait ete | >| raisonnable que ce ne soit pas le cas. | > | > Je crois qu'il y a des indications dans la norme qu'on peut déduire | > | > sizeof (void*) == sizeof (char*) | | 6.2.5/26 | A pointer to void shall have the same representation and alignment | requirements as a pointer to a character type. | | > && sizeof (void*) >= sizeof (T*) | | Ca, j'ai pas vu.
Tu peux caster T* en void* sans perte d'information.
-- Gaby
Laurent Deniau
Jean-Marc Bourguet wrote:
Laurent Deniau writes:
A quoi servirait ce tag?
A ce qu'on veut. Imagine une machine concue pour executer du lisp avec de l'assistance hard, le tag peut etre necessaire pour faire qqch du pointeur mais pas pour trimbaler un void*. J'aurais tendance a
Il me semble que sur Lisp, les types de base ont chacun un tas specialise donc il n'est pas necessaire d'utiliser un tag pour determiner le type du pointeur.
C'est une implementation possible. Une autre est d'utiliser le fait que les pointeurs sont alignes et donc mettre un tag dans les bits de poids faible.
Le meme que le T* originel. Quel probleme?
Quel est le tag du T* originel issu de malloc()?
malloc renvoie un void*, donc sans tag.
Comment T* et void* peuvent avoir des tailles differentes dans ce cas?
t* est un struct { tag* the_tag; void* the_value; };
Un cast met le tag adequat.
Si le tag correspond toujours au type du pointeur, quel est l'interet? Le C connait deja le type du pointeur.
a+, ld.
Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
A quoi servirait ce tag?
A ce qu'on veut. Imagine une machine concue pour executer du lisp
avec de l'assistance hard, le tag peut etre necessaire pour faire qqch
du pointeur mais pas pour trimbaler un void*. J'aurais tendance a
Il me semble que sur Lisp, les types de base ont chacun un tas
specialise donc il n'est pas necessaire d'utiliser un tag pour
determiner le type du pointeur.
C'est une implementation possible. Une autre est d'utiliser le fait
que les pointeurs sont alignes et donc mettre un tag dans les bits de
poids faible.
Le meme que le T* originel. Quel probleme?
Quel est le tag du T* originel issu de malloc()?
malloc renvoie un void*, donc sans tag.
Comment T* et void* peuvent avoir des tailles differentes dans ce cas?
t* est un struct {
tag* the_tag;
void* the_value;
};
Un cast met le tag adequat.
Si le tag correspond toujours au type du pointeur, quel est l'interet?
Le C connait deja le type du pointeur.
A ce qu'on veut. Imagine une machine concue pour executer du lisp avec de l'assistance hard, le tag peut etre necessaire pour faire qqch du pointeur mais pas pour trimbaler un void*. J'aurais tendance a
Il me semble que sur Lisp, les types de base ont chacun un tas specialise donc il n'est pas necessaire d'utiliser un tag pour determiner le type du pointeur.
C'est une implementation possible. Une autre est d'utiliser le fait que les pointeurs sont alignes et donc mettre un tag dans les bits de poids faible.
Le meme que le T* originel. Quel probleme?
Quel est le tag du T* originel issu de malloc()?
malloc renvoie un void*, donc sans tag.
Comment T* et void* peuvent avoir des tailles differentes dans ce cas?
t* est un struct { tag* the_tag; void* the_value; };
Un cast met le tag adequat.
Si le tag correspond toujours au type du pointeur, quel est l'interet? Le C connait deja le type du pointeur.
a+, ld.
Gabriel Dos Reis
"Antoine Leca" writes:
| En , Gabriel Dos Reis va escriure: | > Je crois qu'il y a des indications dans la norme qu'on peut déduire | > | > sizeof (void*) >= sizeof (T*) | > | > parce que void* doit pouvoir contenir des pointeurs sur n'importe quel | > objet. | | Penses-tu à 6.3.2.3p1 | | A pointer to /void/ may be converted to or from a pointer to any | incomplete or object type. A pointer to any incomplete or object | type may be converted to a pointer to /void/ and back again; the | result shall compare equal to the original pointer. | | Autrement dit ce n'est pas symétrique, la conversion void* => T* ne peut pas | ajouter d'information extérieure (entropie).
Oui, c'est à cela que je pensais.
| Cela étant, cela n'est pas une contrainte sur la représentation des objets. | Comme le disait Jean-Marc, on peut y ajouter des informations de validation | du type T*, par exemple; ou un pointeur vers une fonction de debug qui sait | afficher le contenu de l'objet pointé. Vois pas le souci.
Oui, mais je ne vois pas comment pourrais arriver si
sizeof (void*) < sizeof (T*)
(OK, l'usage de sizeof n'est pas adéquat, il faudrait parler de nombre de bits significatifs, mais je crois que tu vois ce que je vuex dire).
-- Gaby
"Antoine Leca" <root@localhost.gov> writes:
| En m3sm7jw459.fsf@merlin.cs.tamu.edu, Gabriel Dos Reis va escriure:
| > Je crois qu'il y a des indications dans la norme qu'on peut déduire
| >
| > sizeof (void*) >= sizeof (T*)
| >
| > parce que void* doit pouvoir contenir des pointeurs sur n'importe quel
| > objet.
|
| Penses-tu à 6.3.2.3p1
|
| A pointer to /void/ may be converted to or from a pointer to any
| incomplete or object type. A pointer to any incomplete or object
| type may be converted to a pointer to /void/ and back again; the
| result shall compare equal to the original pointer.
|
| Autrement dit ce n'est pas symétrique, la conversion void* => T* ne peut pas
| ajouter d'information extérieure (entropie).
Oui, c'est à cela que je pensais.
| Cela étant, cela n'est pas une contrainte sur la représentation des objets.
| Comme le disait Jean-Marc, on peut y ajouter des informations de validation
| du type T*, par exemple; ou un pointeur vers une fonction de debug qui sait
| afficher le contenu de l'objet pointé. Vois pas le souci.
Oui, mais je ne vois pas comment pourrais arriver si
sizeof (void*) < sizeof (T*)
(OK, l'usage de sizeof n'est pas adéquat, il faudrait parler de nombre
de bits significatifs, mais je crois que tu vois ce que je vuex dire).
| En , Gabriel Dos Reis va escriure: | > Je crois qu'il y a des indications dans la norme qu'on peut déduire | > | > sizeof (void*) >= sizeof (T*) | > | > parce que void* doit pouvoir contenir des pointeurs sur n'importe quel | > objet. | | Penses-tu à 6.3.2.3p1 | | A pointer to /void/ may be converted to or from a pointer to any | incomplete or object type. A pointer to any incomplete or object | type may be converted to a pointer to /void/ and back again; the | result shall compare equal to the original pointer. | | Autrement dit ce n'est pas symétrique, la conversion void* => T* ne peut pas | ajouter d'information extérieure (entropie).
Oui, c'est à cela que je pensais.
| Cela étant, cela n'est pas une contrainte sur la représentation des objets. | Comme le disait Jean-Marc, on peut y ajouter des informations de validation | du type T*, par exemple; ou un pointeur vers une fonction de debug qui sait | afficher le contenu de l'objet pointé. Vois pas le souci.
Oui, mais je ne vois pas comment pourrais arriver si
sizeof (void*) < sizeof (T*)
(OK, l'usage de sizeof n'est pas adéquat, il faudrait parler de nombre de bits significatifs, mais je crois que tu vois ce que je vuex dire).
-- Gaby
Jean-Marc Bourguet
Laurent Deniau writes:
Si le tag correspond toujours au type du pointeur, quel est l'interet?
Correspondre au format defini par le hard qui a besoin du tag?
J'ai pas ecrit que l'interet etait profond, simplement que ca me semblait une implementation conforme.
A+
-- Jean-Marc FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc Site de usenet-fr: http://www.usenet-fr.news.eu.org
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
Si le tag correspond toujours au type du pointeur, quel est
l'interet?
Correspondre au format defini par le hard qui a besoin du tag?
J'ai pas ecrit que l'interet etait profond, simplement que ca me
semblait une implementation conforme.
A+
--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
(Ton séparateur de .sig est invalide. Oui, je sais, tu t'en fous...)
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"C is a sharp tool"
Antoine Leca
En , Gabriel Dos Reis va escriure:
Cela étant, cela n'est pas une contrainte sur la représentation des objets. Comme le disait Jean-Marc, on peut y ajouter des informations de validation du type T*, par exemple; ou un pointeur vers une fonction de debug qui sait afficher le contenu de l'objet pointé. Vois pas le souci.
Oui, mais je ne vois pas comment pourrais arriver si
sizeof (void*) < sizeof (T*)
(OK, l'usage de sizeof n'est pas adéquat, il faudrait parler de nombre de bits significatifs, mais je crois que tu vois ce que je vuex dire).
Inutile de préciser que je n'ai pas testé, j'élucubre, dans la grande tradition des Antoine!
En m3y8hbt3o9.fsf@merlin.cs.tamu.edu, Gabriel Dos Reis va escriure:
Cela étant, cela n'est pas une contrainte sur la représentation des
objets. Comme le disait Jean-Marc, on peut y ajouter des
informations de validation du type T*, par exemple; ou un pointeur
vers une fonction de debug qui sait afficher le contenu de l'objet
pointé. Vois pas le souci.
Oui, mais je ne vois pas comment pourrais arriver si
sizeof (void*) < sizeof (T*)
(OK, l'usage de sizeof n'est pas adéquat, il faudrait parler de nombre
de bits significatifs, mais je crois que tu vois ce que je vuex dire).
Cela étant, cela n'est pas une contrainte sur la représentation des objets. Comme le disait Jean-Marc, on peut y ajouter des informations de validation du type T*, par exemple; ou un pointeur vers une fonction de debug qui sait afficher le contenu de l'objet pointé. Vois pas le souci.
Oui, mais je ne vois pas comment pourrais arriver si
sizeof (void*) < sizeof (T*)
(OK, l'usage de sizeof n'est pas adéquat, il faudrait parler de nombre de bits significatifs, mais je crois que tu vois ce que je vuex dire).
parce que void* doit pouvoir contenir des pointeurs sur n'importe quel objet. Je crois également que C99 demande
Ah, voilà qui est plus clair. Ca veux dire que pour allouer un tableau de pointeurs générique, on doit faire
void *a = malloc (sizeof *a *taille)
Un tel tableau est alors capable de recevoir les adresses de n'importe quel objet. On est bien d'accord ?
Non. Il n'y a rien dans la norme qui interdit que la taille d'un T* pourrait être supérieure à la taille d'un void*. Le fait qu'un void* doit être capable de stocker l'information "adresse" d'un T* ne l'empêche pas le T* de stocker une information spéfifique pour son type.
-- Horst
Emmanuel Delahaye <emdel@YOURBRAnoos.fr> wrote:
Gabriel Dos Reis wrote on 09/11/04 :
Je crois qu'il y a des indications dans la norme qu'on peut déduire
parce que void* doit pouvoir contenir des pointeurs sur n'importe quel
objet. Je crois également que C99 demande
Ah, voilà qui est plus clair. Ca veux dire que pour allouer un tableau
de pointeurs générique, on doit faire
void *a = malloc (sizeof *a *taille)
Un tel tableau est alors capable de recevoir les adresses de n'importe
quel objet. On est bien d'accord ?
Non. Il n'y a rien dans la norme qui interdit que la taille d'un T*
pourrait être supérieure à la taille d'un void*. Le fait qu'un void*
doit être capable de stocker l'information "adresse" d'un T* ne
l'empêche pas le T* de stocker une information spéfifique pour son
type.
parce que void* doit pouvoir contenir des pointeurs sur n'importe quel objet. Je crois également que C99 demande
Ah, voilà qui est plus clair. Ca veux dire que pour allouer un tableau de pointeurs générique, on doit faire
void *a = malloc (sizeof *a *taille)
Un tel tableau est alors capable de recevoir les adresses de n'importe quel objet. On est bien d'accord ?
Non. Il n'y a rien dans la norme qui interdit que la taille d'un T* pourrait être supérieure à la taille d'un void*. Le fait qu'un void* doit être capable de stocker l'information "adresse" d'un T* ne l'empêche pas le T* de stocker une information spéfifique pour son type.