IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Conversion void* et double


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut Conversion void* et double
    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.

  2. #2
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    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.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    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...

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Médinoc
    void* est un pointeur générique, mais reste un pointeur.
    double, c'est un entier.
    Tu a voulu dire nombre à virgule flottante...

    Thierry

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut
    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 **

  6. #6
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    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 *

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut
    merci,

    encore un question alors pourquoi le type float qui est sur 4octets interdis aussi cela ?

  8. #8
    Membre averti Avatar de Bob.Killer
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    336
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 336
    Points : 332
    Points
    332
    Par défaut
    Il faut utiliser les bonnes fonctions

    atol() Convert string to long (function)
    atoi() Convert string to integer (function)
    atof() Convert string to double (function)

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut
    non non j'ai juste fais unmauvais copier coller je corrige le probleme n'est pas la

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Bob.Killer
    Il faut utiliser les bonnes fonctions

    atol() Convert string to long (function)
    atoi() Convert string to integer (function)
    atof() Convert string to double (function)
    Obsolète! On utilise aujourd'hui strtol(), strtol() et strtod() respectivement qui permettent une meilleure gestion des erreurs que ato*().

    Thierry

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut
    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 ?

  12. #12
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Ca y'est j'ai compris, on s'est emmelé les pinceaux.

    tabgen[i]= (long *)(atol(tabE[i]));

    et pas ca :

    tabgen[i]= (double *)(atof(tabE[i]));
    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.
    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]));

  13. #13
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par Gruik
    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...

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut
    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

  15. #15
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Citation Envoyé par crocodilex
    Je ne vois pas trop l'interêt. Je trouve cette écriture complètement absurde...
    Hé ho, j'ai pas dit qu'il fallait faire ça, c'était pour tester ce qu'autorisait le compilateur

  16. #16
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    Citation Envoyé par EnigmuS
    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
    Ok, j'ai dit des conneries alors (sur le coup du double trop grand pour rentrer dans un pointeur)

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    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...

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Points : 13
    Points
    13
    Par défaut
    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

  19. #19
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 729
    Points
    1 729
    Par défaut
    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

    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);
    Une idee courante est de creer une structure contenant
    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

  20. #20
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par EnigmuS
    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 ?
    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.

    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:
    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;
    }
    Thierry

Discussions similaires

  1. [Conversion]int to double
    Par frouge dans le forum Général Java
    Réponses: 6
    Dernier message: 03/02/2012, 09h34
  2. Conversion de type double en texte
    Par CoachMac dans le forum C
    Réponses: 17
    Dernier message: 14/10/2006, 19h29
  3. [VB.NET]Comment obtenir conversion exacte Single>Double?
    Par Misterburma dans le forum VB.NET
    Réponses: 9
    Dernier message: 09/02/2006, 22h24
  4. Problème conversion float vers double
    Par jhenaff dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 27/01/2006, 10h39
  5. conversion string en double
    Par zmatz dans le forum SL & STL
    Réponses: 2
    Dernier message: 14/10/2005, 22h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo