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 :
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*.
C'est possible ça?
double** n'est pas censé avoir la même taille que void**.
C'est possible, mais c'est hors-sujet. Je parle de void* et non de void**. Est-ce que la taille d'un double * peut être différente de celle d'un void * ? Si c'est vrai, malloc() ne fonctionne pas.
-- 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"
Gabriel Dos Reis wrote on 08/11/04 :
Emmanuel Delahaye <emdel@YOURBRAnoos.fr> writes:
Jean-Marc Bourguet wrote on 07/11/04 :
void* est un cas particulier. Il faut un cast pour les
autres. Note que ça peut être dangereux dans les cas où
double* n'a pas la même taille que void*.
C'est possible ça?
double** n'est pas censé avoir la même taille que void**.
C'est possible, mais c'est hors-sujet. Je parle de void* et non de
void**. Est-ce que la taille d'un double * peut être différente de
celle d'un void * ? Si c'est vrai, malloc() ne fonctionne pas.
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*.
C'est possible ça?
double** n'est pas censé avoir la même taille que void**.
C'est possible, mais c'est hors-sujet. Je parle de void* et non de void**. Est-ce que la taille d'un double * peut être différente de celle d'un void * ? Si c'est vrai, malloc() ne fonctionne pas.
-- 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"
Emmanuel Delahaye
Jean-Marc Bourguet wrote on 08/11/04 :
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ? J'arrête le C!
-- 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"
Jean-Marc Bourguet wrote on 08/11/04 :
void* est un cas particulier. Il faut un cast pour les
autres. Note que ça peut être dangereux dans les cas où
double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ? J'arrête le C!
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ? J'arrête le C!
-- 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"
Emmanuel Delahaye
Nico wrote on 07/11/04 :
Les fonctions mat_new et mat_free fonctionnent seulement si un void* a la mème taille et la même représentation binaire qu'un double*. Puisque ces deux propriétés ne sont pas imposées par la norme du langage C la conversion n'est pas sure et il faut un cast pour dire au compilateur "je sais que cela fonctionnne".
je compile avec l'option -ansi, pourquoi mon compilateur ne me le dit pas ?
sans doute parce que le sur cette implémentation, il n'y a pas de risque. Un outil d'analyse indépendant de l'implémentation comme *Lint pourrait le dire.
-- 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"
Nico wrote on 07/11/04 :
Les fonctions mat_new et mat_free fonctionnent seulement si un void* a
la mème taille et la même représentation binaire qu'un double*.
Puisque ces deux propriétés ne sont pas imposées par la norme du
langage C la conversion n'est pas sure et il faut un cast pour dire au
compilateur "je sais que cela fonctionnne".
je compile avec l'option -ansi, pourquoi mon compilateur ne me le dit pas ?
sans doute parce que le sur cette implémentation, il n'y a pas de
risque. Un outil d'analyse indépendant de l'implémentation comme *Lint
pourrait le dire.
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
Les fonctions mat_new et mat_free fonctionnent seulement si un void* a la mème taille et la même représentation binaire qu'un double*. Puisque ces deux propriétés ne sont pas imposées par la norme du langage C la conversion n'est pas sure et il faut un cast pour dire au compilateur "je sais que cela fonctionnne".
je compile avec l'option -ansi, pourquoi mon compilateur ne me le dit pas ?
sans doute parce que le sur cette implémentation, il n'y a pas de risque. Un outil d'analyse indépendant de l'implémentation comme *Lint pourrait le dire.
-- 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"
Emmanuel Delahaye
Richard Delorme wrote on 08/11/04 :
Ou encore plus sûr :
void **m = calloc(nrow, sizeof(*m));
Pourquoi calloc() est plus sûr que malloc() ? calloc() ne crée pas un tableau de pointeurs nuls, sauf sur les implémentations où le pointeur nul est représenté par des bits tous nuls.
Et c'est repartit pour NULL!!!
-- 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"
Richard Delorme wrote on 08/11/04 :
Ou encore plus sûr :
void **m = calloc(nrow, sizeof(*m));
Pourquoi calloc() est plus sûr que malloc() ?
calloc() ne crée pas un tableau de pointeurs nuls, sauf sur les
implémentations où le pointeur nul est représenté par des bits tous nuls.
Et c'est repartit pour NULL!!!
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
Pourquoi calloc() est plus sûr que malloc() ? calloc() ne crée pas un tableau de pointeurs nuls, sauf sur les implémentations où le pointeur nul est représenté par des bits tous nuls.
Et c'est repartit pour NULL!!!
-- 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"
Jean-Marc Bourguet
Emmanuel Delahaye writes:
C'est possible, mais c'est hors-sujet. Je parle de void* et non de void**. Est-ce que la taille d'un double * peut être différente de celle d'un void * ?
Oui.
Si c'est vrai, malloc() ne fonctionne pas.
Pourquoi?
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
Emmanuel Delahaye <emdel@YOURBRAnoos.fr> writes:
C'est possible, mais c'est hors-sujet. Je parle de void*
et non de void**. Est-ce que la taille d'un double * peut
être différente de celle d'un void * ?
Oui.
Si c'est vrai, malloc() ne fonctionne pas.
Pourquoi?
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
C'est possible, mais c'est hors-sujet. Je parle de void* et non de void**. Est-ce que la taille d'un double * peut être différente de celle d'un void * ?
Oui.
Si c'est vrai, malloc() ne fonctionne pas.
Pourquoi?
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
Jean-Marc Bourguet
Emmanuel Delahaye writes:
Jean-Marc Bourguet wrote on 08/11/04 :
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*. C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ?
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.
J'arrête le C!
Tu vis ta vie comme tu l'entends.
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
Emmanuel Delahaye <emdel@YOURBRAnoos.fr> writes:
Jean-Marc Bourguet wrote on 08/11/04 :
void* est un cas particulier. Il faut un cast pour les
autres. Note que ça peut être dangereux dans les cas où
double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ?
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.
J'arrête le C!
Tu vis ta vie comme tu l'entends.
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
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*. C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ?
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.
J'arrête le C!
Tu vis ta vie comme tu l'entends.
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
Richard Delorme
Richard Delorme wrote on 08/11/04 :
Ou encore plus sûr :
void **m = calloc(nrow, sizeof(*m));
Pourquoi calloc() est plus sûr que malloc() ? calloc() ne crée pas un tableau de pointeurs nuls, sauf sur les implémentations où le pointeur nul est représenté par des bits tous nuls.
Et c'est repartit pour NULL!!!
Mais non, je n'ai pas parlé du pointeur nul constant.
-- Richard
Richard Delorme wrote on 08/11/04 :
Ou encore plus sûr :
void **m = calloc(nrow, sizeof(*m));
Pourquoi calloc() est plus sûr que malloc() ?
calloc() ne crée pas un tableau de pointeurs nuls, sauf sur les
implémentations où le pointeur nul est représenté par des bits tous nuls.
Et c'est repartit pour NULL!!!
Mais non, je n'ai pas parlé du pointeur nul constant.
Pourquoi calloc() est plus sûr que malloc() ? calloc() ne crée pas un tableau de pointeurs nuls, sauf sur les implémentations où le pointeur nul est représenté par des bits tous nuls.
Et c'est repartit pour NULL!!!
Mais non, je n'ai pas parlé du pointeur nul constant.
-- Richard
Gabriel Dos Reis
Emmanuel Delahaye writes:
| Gabriel Dos Reis wrote on 08/11/04 : | > Emmanuel Delahaye writes: | > | >> Jean-Marc Bourguet wrote on 07/11/04 : | >> | >>> void* est un cas particulier. Il faut un cast pour les | >>> autres. Note que ça peut être dangereux dans les cas où | >>> double* n'a pas la même taille que void*. | >> C'est possible ça? | > | > double** n'est pas censé avoir la même taille que void**. | | C'est possible, mais c'est hors-sujet. Je parle de void* et non de | void**. Est-ce que la taille d'un double * peut être différente de | celle d'un void * ?
Oui.
| Si c'est vrai, malloc() ne fonctionne pas.
Quelle est la chaîne logique d'inférences qui t'amène à cette conclusion ?
-- Gaby
Emmanuel Delahaye <emdel@YOURBRAnoos.fr> writes:
| Gabriel Dos Reis wrote on 08/11/04 :
| > Emmanuel Delahaye <emdel@YOURBRAnoos.fr> writes:
| >
| >> Jean-Marc Bourguet wrote on 07/11/04 :
| >>
| >>> void* est un cas particulier. Il faut un cast pour les
| >>> autres. Note que ça peut être dangereux dans les cas où
| >>> double* n'a pas la même taille que void*.
| >> C'est possible ça?
| >
| > double** n'est pas censé avoir la même taille que void**.
|
| C'est possible, mais c'est hors-sujet. Je parle de void* et non de
| void**. Est-ce que la taille d'un double * peut être différente de
| celle d'un void * ?
Oui.
| Si c'est vrai, malloc() ne fonctionne pas.
Quelle est la chaîne logique d'inférences qui t'amène à cette
conclusion ?
| Gabriel Dos Reis wrote on 08/11/04 : | > Emmanuel Delahaye writes: | > | >> Jean-Marc Bourguet wrote on 07/11/04 : | >> | >>> void* est un cas particulier. Il faut un cast pour les | >>> autres. Note que ça peut être dangereux dans les cas où | >>> double* n'a pas la même taille que void*. | >> C'est possible ça? | > | > double** n'est pas censé avoir la même taille que void**. | | C'est possible, mais c'est hors-sujet. Je parle de void* et non de | void**. Est-ce que la taille d'un double * peut être différente de | celle d'un void * ?
Oui.
| Si c'est vrai, malloc() ne fonctionne pas.
Quelle est la chaîne logique d'inférences qui t'amène à cette conclusion ?
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ? J'arrête le C!
T1* -> T2* OK si T1* contient un alignement compatible avec T2*
si sizeof(T1*) > sizeof(T2*) l'operateur de cast a le droit d'enlever des bits de poids faible pour reduire la taille du pointeur T1* a la taille de T2*.
si sizeof(T1*) < sizeof(T2*) l'operateur de cast a le droit d'ajouter des bits pour agrandir la taille du pointeur T1* a la taille de T2*. Ce qui veut dire que T1*+bits_ajoutes doit etre compatible avec T2* sinon BOUM.
par specialisation
T* -> void* OK void* -> T* OK si void* contient un alignement compatible avec T*
parce que void* est capable de contenir tous les alignements necessaires au C, c'est a dire qu'il a la taille maximale qu'un pointeur peut avoir. malloc renvoie un void* compatible avec T*, qqs T.
par transition
T* -> void* -> T* OK (puisque T* -> T* OK) T1* -> void* -> T2* OK seulement si T1* -> T2* OK
mais
void* -> T* -> void* OK seulement si void* -> T* OK
a+, ld.
Emmanuel Delahaye wrote:
Jean-Marc Bourguet wrote on 08/11/04 :
void* est un cas particulier. Il faut un cast pour les
autres. Note que ça peut être dangereux dans les cas où
double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ? J'arrête le C!
T1* -> T2* OK si T1* contient un alignement compatible avec T2*
si sizeof(T1*) > sizeof(T2*) l'operateur de cast a le droit d'enlever
des bits de poids faible pour reduire la taille du pointeur T1* a la
taille de T2*.
si sizeof(T1*) < sizeof(T2*) l'operateur de cast a le droit d'ajouter
des bits pour agrandir la taille du pointeur T1* a la taille de T2*. Ce
qui veut dire que T1*+bits_ajoutes doit etre compatible avec T2* sinon BOUM.
par specialisation
T* -> void* OK
void* -> T* OK si void* contient un alignement compatible avec T*
parce que void* est capable de contenir tous les alignements necessaires
au C, c'est a dire qu'il a la taille maximale qu'un pointeur peut avoir.
malloc renvoie un void* compatible avec T*, qqs T.
par transition
T* -> void* -> T* OK (puisque T* -> T* OK)
T1* -> void* -> T2* OK seulement si T1* -> T2* OK
mais
void* -> T* -> void* OK seulement si void* -> T* OK
void* est un cas particulier. Il faut un cast pour les autres. Note que ça peut être dangereux dans les cas où double* n'a pas la même taille que void*.
C'est possible ça?
Quoi que void* n'ait pas la meme taille que double*? Oui.
alors
double *p = malloc (sizeof *p * 12);
ne fonctionne pas ? J'arrête le C!
T1* -> T2* OK si T1* contient un alignement compatible avec T2*
si sizeof(T1*) > sizeof(T2*) l'operateur de cast a le droit d'enlever des bits de poids faible pour reduire la taille du pointeur T1* a la taille de T2*.
si sizeof(T1*) < sizeof(T2*) l'operateur de cast a le droit d'ajouter des bits pour agrandir la taille du pointeur T1* a la taille de T2*. Ce qui veut dire que T1*+bits_ajoutes doit etre compatible avec T2* sinon BOUM.
par specialisation
T* -> void* OK void* -> T* OK si void* contient un alignement compatible avec T*
parce que void* est capable de contenir tous les alignements necessaires au C, c'est a dire qu'il a la taille maximale qu'un pointeur peut avoir. malloc renvoie un void* compatible avec T*, qqs T.
par transition
T* -> void* -> T* OK (puisque T* -> T* OK) T1* -> void* -> T2* OK seulement si T1* -> T2* OK
mais
void* -> T* -> void* OK seulement si void* -> T* OK