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 :

[langage] constantes, structures, cast de pointeurs de fonctions


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 760
    Points : 626
    Points
    626
    Par défaut [langage] constantes, structures, cast de pointeurs de fonctions
    Bonjour,
    J'ai plusieur problemes de theorique avec le C.

    Premierement, comment peut on/doit on passer des structures a des fonctions en impliquant que celle ci ne doit pas etre modifiée ?
    Pour l'instant, je passe ma structure en copie (donc sans pointeur) ainsi si celle-ci est modifiée, la "vraie" structure ne l'est pas. Est il possible de passer un pointeur vers une structure constante? Et, dans ce cas la, que signifie structure constante ? Cela influence t il les membres et si oui, que ce passe t il si un de ses membres est un pointeur ?

    (Passer la structure en reference est plus econome que la passer en copie, mais peut on interdire toute modification ?)

    Deuxièmement, est il possible de definir dans une structure des attributs constants, si oui, comment les initialise t on ? (Car j'imagine que dès que la structure est reservée en memoire, ses attributs constants devraient deja etre definis... )

    Troisièmement, est il possible de faire des cast de pointeurs de fonctions ?(J'ai pas reussi a trouve comment).
    Par exemple on a , int f(int , long ) mais on souhaite avoir un pointeur sur short f(long short ). Ou alors, est on obligé de creer une fonction intermediaire afin de realiser l'"interface".
    De meme, mais je pense que c'est cela est vraiment utoptique, peut on passer un partie des parametres directement ?
    C'est a dire en reprenant int f(int, long b) et que je souhaire utiliser une fonction short f(long int), et il possible de faire b=5 (par exemple) ?

    D'avance merci

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par TabrisLeFol
    Premierement, comment peut on doit on passer des structures a des fonctions en impliquant que celle ci ne doit pas etre modifiée ?
    Pour être efficace, on passe l'adresse avec un qualificateur const qui rend les membres de la structure non modifiables :
    que ce passe t il si un de ses membres est un pointeur ?
    Un membre pointeur devient non modifiable, mais ce qui est pointé reste modifiable, si il l'était, bien sûr.
    (Passer la structure en reference est plus econome que la passer en copie, mais peut on interdire toute modification ?)
    On ne peut pas 'interdire' à un programmeur de se tirer une balle dans le pied, car un cast suffit à briser la 'constantness'. Mais le comportement devient alors indéterminé. Le C n'est pas un langage de bidouilleurs... Plus que jamais "C is a sharp tool"...
    Deuxièmement, est il possible de definir dans une structure des attributs constants, si oui, comment les initialise t on ? (Car j'imagine que des que la structure est reservée en memoire, ses attributs constants devraient deja etre definis... )
    C'est quoi un attribut ? Je ne connais que les membres (ou éléments).

    Comme pour une variable simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       int const c; /* non sens */
       c = 123; /* bah, non, c'est 'const'... */
    Donc, on fait comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       int const c = 123;
    Tu parles de ce cas là :
    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
     
    struct data
    {
       int const x;
       int y;
    };
     
    int main (void)
    {
       struct data data;
     
       data.x = 123; /* bug */
       data.y = 456;
     
       return 0;
    }
    donc on fait comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct data
    {
       int const x;
       int y;
    };
     
    int main (void)
    {
       struct data data = {123};
     
       data.y = 456;
     
       return 0;
    }
    Sil il faut faire une initialisation après définition (allocation dynamique, par exemple), on doit utiliser memcpy() :
    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
    18
    19
    #include <string.h>
     
    struct data
    {
       int const x;
       int y;
    };
     
    int main (void)
    {
       struct data z = {123};
       struct data data;
     
       memcpy (&data, &z, sizeof data);
     
       data.y = 456;
     
       return 0;
    }
    Troisièmement, est il possible de faire des cast de pointeurs de fonctions ?(J'ai pas reussi a trouve comment).
    Par exemple on a , int f(int a, long b) mais on souhaite avoir un pointeur sur short f(long int, short b). Ou alors, est on obligé de creer une fonction intermediaire afin de realiser l'"interface".
    C'est techniquement possible, mais peu recommandé, car on se prive des vérifications du compilateur.

    Le cast est plutôt gore, alors on passe par un typedef qui allège considérablement l'écriture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef short fb_f (long int, short b);
     
    int fa(int a, long b);
     
    {
       fb_f *pf = (fb_f *) fa;
    }
    A toi de savoir ce que tu fais, tu travailles sans filet...
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 760
    Points : 626
    Points
    626
    Par défaut
    Merci beaucoup, effectivement, il s'agit peut etre de "membres" mais j'ai l'habitude d'utiliser attributs pour le membre des objets... (Oui, le C n'est pas un language orienté objet.) Mais j'amalgame objets et struct, meme si je conçoit leur difference.

    Pour l'allocation dynamque, c'était effectivement mon problème. (Je dois avouer que je ne connaissais meme pas le static, avec les membres contants.) Dans l'exemple, si j'ai bien compris le struct data data aurait pu etre alloué dynamiquement par un malloc.

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par TabrisLeFol
    Dans l'exemple, si j'ai bien compris le struct data data aurait pu etre alloué dynamiquement par un malloc.
    Oui.
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 760
    Points : 626
    Points
    626
    Par défaut
    Juste une petite confirmation sur la protection des donnees.

    Normalement, en l'absence de membres constants, ceci devrait etre legal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct data z = {123};
    struct data* data = malloc(sizeof(*data));
    *data = z;
    Ce qui signifie que
    * lorsqu'il y a un membre constant cela ne marche pas, car une partie de la plage de donnee reservee pour la struct est "read-only"
    * memcopy permet de surpasser la protection const

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par TabrisLeFol
    Juste une petite confirmation sur la protection des donnees.

    Normalement, en l'absence de membres constants, ceci devrait etre legal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct data z = {123};
    struct data* data = malloc(sizeof(*data));
    *data = z;
    OK, c'est comme ça que j'initialise les structures dynamiques :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       T *p = malloc(sizeof *p)
       if (p != NULL)
       {
          static const z = {0};
          *p = z;
          /* ... */
    simple, rapide, portable.
    Ce qui signifie que
    * lorsqu'il y a un membre constant cela ne marche pas, car une partie de la plage de donnee reservee pour la struct est "read-only"
    * memcopy permet de surpasser la protection const
    Oui. (au fait, c'est memcpy())...
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 760
    Points : 626
    Points
    626
    Par défaut
    Hum, ok.

    Par contre, le static, il n'est pas thread safe ? Pour des processus independants, l'espace memoire de la fonction (et donc les variables statiques) seront separées, mais pas pour des threads ? non ?

    (memcopy s'était une erreur, oui.)

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est constant, donc aucun conflit possible.
    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.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 760
    Points : 626
    Points
    626
    Par défaut
    Ah, oui. J'étais resté sur mon probleme d'allouer dynamiquement un membre constant d'une structure elle-meme allouer dynamiquement. (La solution étant le memcpy.)

    Dans ce cas ci, le membre de toutes les structures sera 0. Le static const est donc comme un model d'initialisation pour la structure. Et cet exemple ne concernait pas le cas, ou un membre était 'const'.

    Merci beaucoup.

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par TabrisLeFol
    Par contre, le static, il n'est pas thread safe ?
    Et ? C'est en lecture seule. Quel est le problème ?
    Pas de Wi-Fi à la maison : CPL

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/10/2014, 11h38
  2. Réponses: 7
    Dernier message: 08/04/2006, 12h18
  3. Structure, pointeur et fonction...
    Par Linaa dans le forum C
    Réponses: 15
    Dernier message: 04/12/2005, 13h12
  4. Pointeur de fonction et structure
    Par Trunks dans le forum C
    Réponses: 6
    Dernier message: 07/10/2005, 00h32
  5. [langage] Pointeur sur fonction
    Par Fanch.g dans le forum Langage
    Réponses: 2
    Dernier message: 02/10/2004, 10h43

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