Bonjour,
pourquoi en C on ne peut pas convertir un void* en double je croyais que le type void etait le type générique ?
merci d'avance.
Bonjour,
pourquoi en C on ne peut pas convertir un void* en double je croyais que le type void etait le type générique ?
merci d'avance.
Salut,
void * est le type de pointeur générique, pas le type générique. Tu peux caster un "void *" en "double *" mais pas en "double".
Le type void tout court n'a pas de sens, à part dans les signatures de fonction.
void* est un pointeur générique, mais reste un pointeur.
double, c'est un nombre.
Edit: Non seulement je me fais griller, mais en plus je dis des conneries...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Tu a voulu dire nombre à virgule flottante...Envoyé par Médinoc
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
ah ok merci et pourquoi ca ca marche :
tabgen[i]= (long *)(atol(tabE[i]));
et pas ca :
tabgen[i]= (double *)(atof(tabE[i]));
avec tabgen[i] de type void **
Si on veut se la jouer chacal, on peut se permettre de caster un int/long en void *, car il s'avere qu'un pointeur (de n'importe quel type) prend la meme place qu'un entier long sur pas mal de plateformes.
Mais faire ça c'est casser l'abstraction du sizeof
double prend plus de place qu'un int et donc ça ne rentre pas dans un void *
merci,
encore un question alors pourquoi le type float qui est sur 4octets interdis aussi cela ?
Il faut utiliser les bonnes fonctions
atol() Convert string to long (function)
atoi() Convert string to integer (function)
atof() Convert string to double (function)
non non j'ai juste fais unmauvais copier coller je corrige le probleme n'est pas la
Obsolète! On utilise aujourd'hui strtol(), strtol() et strtod() respectivement qui permettent une meilleure gestion des erreurs que ato*().Envoyé par Bob.Killer
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Une idée sur le fait que on puisse convertir void * en int/long (meme si c'est pas propre) à cause de la representation en memoire de 4octets et pas en float qui est aussi sur 4octets ?
Ca y'est j'ai compris, on s'est emmelé les pinceaux.
Ici, le probleme n'est pas dans l'affectation du "long *" ou "double *" dans tabgen[i], le probleme est le castage du atol() et du atof() en pointeur.tabgen[i]= (long *)(atol(tabE[i]));
et pas ca :
tabgen[i]= (double *)(atof(tabE[i]));
atof() retourne tout le temps un double, donc tu pourras jamais caster le retour de atof en pointeur.
Si atof retournait un float alors ça serait peut être possible
Yaurait qu'a tester ceci
(double *)((float)atof(tabE[i]));
Je ne vois pas trop l'interêt. Je trouve cette écriture complètement absurde...Envoyé par Gruik
Oui mais mon compilo m'empeche de convertir un float ou un double vers leur pointeur respectif et donc encore moi un float vers un pointeur sur double c'est illégal
d'ailleurs c'est bizarre de pas pouvoir caster un float en float* alors qu'un long en long* on peut
Hé ho, j'ai pas dit qu'il fallait faire ça, c'était pour tester ce qu'autorisait le compilateurEnvoyé par crocodilex
Ok, j'ai dit des conneries alors (sur le coup du double trop grand pour rentrer dans un pointeur)Envoyé par EnigmuS
Il faut dire que dans tous les cas, ce genre de transtypage est un hack affreux.
Les seuls types de nombres qu'on devrait pouvoir convertir en pointeurs, sont intptr_t et consorts...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
bein si tu sais comment on déreference un pointeur (on obtient la valeur pointée) en assembleur ca m'intéresse car si je convertis comme ca pour les mettre dans le tableau génériquec'est pour générer la signature d'un appel à une DLL qui prend n'importe quoi comme type (pointeur ou pas) et qui est appelé via de l'assembleur alors quand j'ai des pointeurs sur double ca va mais quand j'ai des doubles ca aime moins
enfin je découvre et je galére y a surement d'autre solution et je vois bien que c'est moche![]()
Bah le type du pointeur peut être modifié (on peut tres bien mettre un "double *" dans un "void *") ce qu'il faut pas faire c'est mettre un "scalaire" (entier, flottant, structure) dans un pointeur. Si ça doit arriver : donner l'adresse de ce scalaire -- à condition qu'il soit disponible tant qu'on maintient une pointeur sur lui -- la solution la plus sure est alors de "mallocopier" ce scallaire et de libérer cette copie quand on en a plus besoin
Une idee courante est de creer une structure contenant
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 void * ptr_gen; double mon_scalaire; double * tmp_ptr; mon_scalaire = 42.42; tmp_ptr = malloc(sizeof mon_scalaire); memcpy(tmp_ptr, &mon_scalaire, sizeof mon_scalaire); ptr_gen = tmp_ptr; /* -- plus loin : utilisation */ tmp_ptr = ptr_gen; /* à condition de savoir que c'est en fait un pointeur sur double */ mon_scalaire = *tmp_ptr; /* -- plus loin : liberation */ free(ptr_gen);
1) le pointeur vers la zone où ya la copie de la valeur
2) un union avec tous les types dont on a besoin
3) un enum indiquant le type
Edit: avec cette structure il n'y a plus besoin de mallocopier un scalaire, une copie simple suffit
Parce qu'une adresse (la valeur d'un pointeur) est un valeur entière. Cela peut donc faire un certain sens de convertir la valeur d'un pointeur en un entier inversément. Par contre, je ne vois aucune raison d'autoriser un cast d'un pointeur en double.Envoyé par EnigmuS
D'ailleurs, la portabilité du cast pointeur <-> entier n'est pas garantie. Selon la norme, le résultat de la conversion d'un entier en un type pointeur est définit par l'implantation. Ce résultat peut en effet ne pas être aligné correctement, et peut ne pas pointer sur un objet du type référencé. La conversion inverse est également définie par l'implantation, et le comportement est indéfini si la valeur du pointeur ne peut être représentée dans le type entier hôte.
A priori, il n'est pas garantit qu'un int ou long puisse recevoir la valeur d'un pointeur. Pour les raisons énoncées ici, la norme C99 a introduit les types intptr_t et uintptr_t, déclarés dans stdint.h, qui ont la propriété suivante:
"N'importe quel pointeur générique valide peut être converti dans ce type, puis re-converti en pointeur sur void, et le résultat de cette double conversion sera comparé égal avec la valeur du pointeur original".
Si vraiment tu tiens à convertir ton pointeur en double, et que ton compilateur est comforme à C99, rien ne t'empêche de procéder en deux temps comme ceci:
Thierry
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <stdio.h> #include <stdint.h> int main(void) { int nombre = 10; int *pNombre = &nombre; uintptr_t pvaleur = (uintptr_t) (void *) pNombre; double pvaleur_dbl = pvaleur; return 0; }
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Partager