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 :

Caster un int en pointeur


Sujet :

C

  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut Caster un int en pointeur
    Salutations !

    Je code depuis quelques jours une implémentation de plusieurs API pour un nouvel OS.

    Deux fonctions de ces API servent à échanger des identifiants de tâches et, pour des raisons historiques certainement, les identifants de tâches sont considérés comme étant des int32_t.

    J'ai donc les deux fonctions suivantes à implémenter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int32_t getCurrentTaskID(void); // renvoie l'ID de la tache courante
    wakeup(int32_t ID); // reveille la tache reperee par ID
    Pour les précédentes implémentations, les OS géraient les ID avec des int32_t (où le "historiques" ci-dessus) mais le nouvel ID utilise lui des TaskHandle qui correspondent à des pointeurs sur void :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void * TaskHandle;
    Etant sur une architecture 32 bits et supposant donc qu'un pointeur était stocké dans int32_t, j'ai tenté de renvoyer avec getCurrentTaskID() l'adresse de ma variable handle ; avec la fonction wakeup(), je caste l'int32_t en TaskHandle*, je récupère son contenu et je suis arrivé à quelque chose de fonctionnel.

    En faisant cela, je me suis rappelé de ce qu'avait dit diogene ces jours-ci.

    Question bête : comment faire mieux ?

    Merci d'avance pour vos idées !

  2. #2
    Membre chevronné
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Par défaut
    L'API de l'OS sur lequel tu veux implémenter ton programme me rappelle qq chose, serait-ce FreeRTOS ?

    Ceci étant dit, le mieux est d'après moi que ton interface soit modifiée, pour permettre à la plateforme cible d'accepter un type différent de int32_t pour identifier des taches. Un truc genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #ifdef SYSTEM_DONT_JE_CONNAIS_PAS_LE_NOM
    typedef TaskHandle Taskid;
    #else
    typede int32_t Taskid;
    #endif
     
    Taskid getCurrentTaskID(void); // renvoie l'ID de la tache courante
    wakeup(Taskid ID);
    mais bon c'est pas tjs possible, sinon tu serais pas ici à poser la question.

    Un autre point de vue c'est d'analyser comment ton OS fonctionne et déterminer s'il y a une chance pour qu'un jour le TaskHandle soit hors limite pour un int32. C'est cochon.

    Encore un autre point de vue, c'est de construire une grosse abstraction, avec un tableau en interne qui liste toutes les taches en court et contient les TaskHandle respectifs, et retourner un index sur ce tableau.

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut
    Bien vu, il s'agit de FreeRTOS

    L'idéal serait effectivement une modification de l'API mais ce n'est pas très facile à faire sans risquer de casser la compatibilité. Surtout que l'API est indépendante d'un éventuelle OS sous-jacent.

    En regardant sur le net, j'ai trouvé un type qui pourrait se révéler utile : ptrdiff_t. Il m'a déjà permis de voir que pour mon architecture, int32_t et ptrdiff_t correspondent tous les deux à un signed int. Je peux donc caster comme un cochon sans risque de perdre la partie haute de mon adresse.

    L'idée d'un tableau associatif est tentante mais ça risque d'être une vraie usine à gaz. Je cible pour l'occasion des micro-contrôleurs de type Cortex M3, je n'ai pas une mer de de ressources à ma disposition. L'implémentation de l'API étant dépendant de la plateforme, de l'OS, vérifier comme un cochon si un tel cast marche ou pas est a priori plus "intéressant".

    Au final, ma question est plus : si int32_t et ptrdiff_t correspondent tous les deux au même type, le cast dans les 2 sens est-il garanti pour donner un résultat correct ?

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Normalement, tu devrais te tourner plutôt vers intptr_t ou uintptr_t

    n1256 :
    7.18.1.4 Integer types capable of holding object pointers
    1 The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:
    intptr_t
    The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:
    uintptr_t
    These types are optional.

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut
    J'ai aussi vu ces 2 types. Ils en parlent dans sur le site que j'ai lié dans mon message précédents, disant que c'était même type "réel" mais que les noms faisaient qu'ils étaient plus parlant dans un cas ou dans l'autre. Connais-tu une différence autre que le nom ? En tout cas, cela confirme que je peux faire mon cast pour la plateforme actuelle, puisque les tailles sont en accord.

    D'ailleurs, pourquoi faire une variable signée et une non signée pour faire la même chose ?

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    ptrdiff_t est le type de la différence entre deux pointeurs qui est déjà nativement un entier défini par la norme qui explique bien comment la différence entre deux pointeurs est faite. Il n'y aura donc de ce fait pas de problèmes spécifiques de cast avec un autre type entier. Mais il n'est pas fait logiquement pour représenter des pointeurs en entiers.

    intptr_t ou uintptr_t sont des entiers résultant d'un cast d'un pointeur vers un entier, opération qui est dépendante de l'implémentation. La norme ne dit pas comment cet entier sera obtenu à partir du pointeur et ne garantit en fait qu'une forme de réversibilité du cast. Dans tous les cas, on ne peut faire aucune opération sur ces entiers à part la copie et le cast vers void*.
    La norme donne ces types comme optionnels, ce qui signifie aussi qu'il n'est pas obligatoire que les deux soient définis. Il est probable que si ces deux types sont définis, ils aient la même taille en nombre de bits et que même si ces types entiers représentent alors des étendues de nombre différentes, c'est l'opération de cast vers un void* qui en tiendra compte pour rétablir le bon pointeur. Dans ce cas, les deux sont possibles uniquement pour permettre à l'utilisateur une certaine souplesse en fonction de son code (il peut préférer avoir un type signé ou un type non signé).

    Personnellement, je m'orienterais sans doute vers intptr_t/uintptr_t quitte à devoir faire explicitement un typedef si il n'est pas déjà défini.

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut
    Merci beaucoup pour tes commentaires, je m'en souviendrai le moment où un nouveau portage à risque se présentera. Et je m'en souviendrai aussi pour le reste du temps ^^

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. caster un int en String
    Par Bigoodheart dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 20/10/2010, 15h53
  2. caster un int de 4 octets en 4 octets
    Par dedibox26 dans le forum Débuter
    Réponses: 6
    Dernier message: 09/05/2010, 18h28
  3. Tableau stockant enum(int) ou pointeur
    Par NainTernaute dans le forum Langage
    Réponses: 23
    Dernier message: 04/04/2010, 12h10
  4. caster un int en char sur taille fixe
    Par devdebutantajax dans le forum Windows
    Réponses: 14
    Dernier message: 01/11/2008, 14h24
  5. Caster en int le contenu d'un vector
    Par MinsK dans le forum Langage
    Réponses: 6
    Dernier message: 31/05/2007, 16h59

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