Répondre à la discussion
Affichage des résultats 1 à 17 sur 17

Passage par adresse de paramètre dans une fonction, un doute me taraude...

  1. #1
    mweber

    Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Bonjour à tous

    J'ai un petit problème avec le passage par adresse dans une fonction écrite en langage C (pour microcontrôleur PIC 8 bits (Ça reste du C, sauf que les short sont sur 8 bits)).

    Je désire (à ma fonction) lui passer différent types: entier signés 16 bits, entier signés 8 bits pour qu'elle modifie la valeur.


    Voici un exemple tout bête :
    Code:
    void Ma_fonction(int* _x)           // Ajoute 10 à la valeur passée en argument
      {
      *_x =  *_x  + 10 ;
      }
    
    void main(void)
    {
    int     a = 20;      // Entier codé sur 16 bits
    short b = 30;      // Entier codé sur 8 bits
    
    Ma_fonction(&a);
    Ma_fonction(&b);
    Afficher a;
    Afficher b;
    }
    A la compil j'ai un "suspicious pointer conversion" pour Ma_fonction(&b);
    ...Qui peut être supprimé en remplaçant la ligne par: Ma_fonction((int*)&b);

    Mais j'ai un comportement erratique: la fonction marche bien pour les appels de Ma_fonction(&a);
    mais pas pour les appels de Ma_fonction(&b); Ça marchouille genre symptômes écrasements mémoire

    Pourquoi ? Car pour moi, la taille des pointeurs est la même, quel que soit leur type (char*, int*...) car une adresse reste une adresse

    Et comment résoudre ce problème, sans créer une seconde fonction pour traiter les shorts... et sans modifier toutes mes déclarations de variables short en int... (mémoire ROM et EEPROM limitée pour stocker plus de 50 paramètres)

    Merci pour vos lumières !!

    Matthieu

    -----

    Dernière modification par Antoane ; 02/03/2018 à 09h53. Motif: Ajout de balises code

  2. Publicité
  3. #2
    PA5CAL

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Bonjour

    ]
    Code:
    short b = 30;      // Entier codé sur 8 bits
    Si tu passes un pointeur sur un octet à une fonction pour faire une addition sur 16 bits, alors tu vas modifier l'octet placé à l'adresse suivant cet octet, et donc altérer le contenu de la mémoire.

    Il est donc normal :
    - que le compilateur te mette en garde à propos du type déclaré,
    - que le programme puisse montrer des dysfonctionnements.

  4. #3
    mweber

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Ok merci, c'est bien ce que je pensais; mais.. dans la mesure ou mon addition ne dépasse pas 0xFF, je pensais que l'octet jouxtant le 1er ne serait pas altéré... nan en fait c'est logique !!

    Comment résoudre le problème ?

    Merci
    Dernière modification par mweber ; 02/03/2018 à 10h47.

  5. #4
    PA5CAL

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Eh oui. 0xFF sur 16 bits, c'est 0x00FF, d'où l'écrasement de l'octet de poids fort par un zéro.


    La finalité du typage des variables en C est justement de détecter (ce qui est fait ici) et/ou d'interdire ce cas de figure.

    En langage C, il n'est pas possible de créer une seule fonction qui fasse tantôt une opération, tantôt une autre (l'addition sur 8 bits et l'addition sur 16 bits étant clairement différentes), au gré du type du paramètre qui lui est passé.

    Si tu ne peux pas passer tes short en int, je ne vois pas d'autre moyen que de créer deux fonctions et de modifier ton programme à la main pour utiliser celle qu'il faut dans chaque cas. Les messages (erreurs ou warnings) générés à la compilation devraient pouvoir t'aider dans ce travail.
    Dernière modification par PA5CAL ; 02/03/2018 à 10h50.

  6. #5
    PA5CAL

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Si le but est d'effectuer des traitements sur des éléments dont la nature est variable et n'est pas connue au moment de la compilation (on a alors affaire à une programmation orientée objet), il te faudrait passer un paramètre supplémentaire à la fonction afin d'identifier le type de l'élément traité et de réaliser l'opération adéquate.

    Par exemple :

    Code:
    void Ma_fonction(void *x, unsigned char t)
    {
      if (t==1)
        *(char *)x += 10;
      else
      if (t==2)
        *(int *)x += 10;
    }
    
    #define MA_FONCTION(v) Ma_fonction(&(v), sizeof(v))
    
    ...
    
    int a;
    char b;
    
    MA_FONCTION(a); // addition sur 16 bits
    MA_FONCTION(b); // addition sur 8 bits
    Toutefois, cette solution présente de nombreuses limites et un coût en termes de ressources et de performances ...
    Dernière modification par PA5CAL ; 02/03/2018 à 11h05.

  7. #6
    mweber

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Merci !

    Plutôt que de créer 2 fonctions a peu près identiques je peux faire un truc du genre :

    Code:
    void Ma_fonction(int* _x, short* _y)           // Ajoute 10 à la valeur passée en argument
      {
      if (_x != 0) {printf(" [%d] ", *_x + 11) ; *_x+= 3; }
      if (_y != 0) {printf(" [%d] ", *_y + 15) ; *_y+= 4; }
      
          
      }
    
    void main(void)
    {
    int   a = 10;      // Entier codé sur 16 bits
    short b = 30;      // Entier codé sur 8 bits
    
    
    Ma_fonction(&a, 0);
    Ma_fonction(0, &b);
    
    printf("%d %d", a, b);
    }
    Matthieu
    Dernière modification par JPL ; 02/03/2018 à 13h03. Motif: Correction de balise : l’encadrement se fait avec []

  8. #7
    mweber

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Merci pour les balises "codes"

    Bizarrement la mise en forme (police et autre) n'apparait plus dans mon navigateur Firefox pour le forum... ! Je n'ai que les smileys

    Matt

  9. #8
    JPL

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Vide le cache de ton navigateur (si tu utilises Firefox ce n’est pas instantané) et recharge la page.
    Rien ne sert de penser, il faut réfléchir avant - Pierre Dac

  10. #9
    jacknicklaus

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    tu peux aussi définir l'usage de ta fonction via une macro qui va te calculer automatiquement le deuxième argument par une fonction sizeof()

    Code:
    #define Ma_fonction(a) \
    FonctionDeux(&a,sizeof(a));
    
    
    void FonctionDeux(void * _x, int _size) 
    {
      if (_size == 2) (int*)_x += 10;
      else if (_size == 1 )  (short*)_x += 10;  
    }
    
    void main(void)
    {
    int   a = 10;      // Entier codé sur 16 bits
    short b = 30;      // Entier codé sur 8 bits
    
    
    Ma_fonction(a);
    Ma_fonction(b);
    }

    code éventuellement à tuner, pas de moyen de tester ce moment.
    There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.

  11. #10
    mweber

    [RESOLU] Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Ah oui ! Jolis !

    Merci

    Matthieu

  12. #11
    pm42

    Re : [RESOLU] Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Citation Envoyé par mweber Voir le message
    Ah oui ! Jolis !
    Pas vraiment. On perd le typage, cela suppose que la taille d'un int est 2 et celle d'un short est 1 ce qui n'est pas garanti...
    Par exemple, sur ma machine (et sur de nombreuses autres), la taille d'un short est 2 et celle d'un int est 4.

    Donc le jour où tu passes ton code sur un micro-controlleur 32 bits, ça ne marche plus.

  13. #12
    jacknicklaus

    Re : [RESOLU] Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Citation Envoyé par pm42 Voir le message
    On perd le typage, cela suppose que la taille d'un int est 2 et celle d'un short est 1 ce qui n'est pas garanti...
    effectivement. Mais le cahier des charges précisait : "(pour microcontrôleur PIC 8 bits (Ça reste du C, sauf que les short sont sur 8 bits))."


    Celà dit, c'est facile de conserver le typage :
    Code:
      if (_size == sizeof(int)) (int*)_x += 10;
      else if (_size == sizeof(short) )  (short*)_x += 10;
    There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.

  14. #13
    pm42

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Oui, je ne dis pas que c'est le truc le pire qu'on puisse faire, juste que ce n'est pas forcément à prendre tel quel comme exemple quand on est débutant.
    Ceci dit, j'ai du mal à voir l'intérêt d'écrire du code compliqué pour tout mettre dans 1 seule fonction au lieu d'en faire 2.

    D'autant qu'on peut faire une macro pour faire l'ajout de 10 et qui fonctionnera pour tous les types.
    Dernière modification par pm42 ; 04/03/2018 à 20h54.

  15. #14
    PA5CAL

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Citation Envoyé par jacknicklaus Voir le message
    tu peux aussi définir l'usage de ta fonction via une macro qui va te calculer automatiquement le deuxième argument par une fonction sizeof()

    Code:
    #define Ma_fonction(a) \
    FonctionDeux(&a,sizeof(a));
    
    
    void FonctionDeux(void * _x, int _size) 
    {
      if (_size == 2) (int*)_x += 10;
      else if (_size == 1 )  (short*)_x += 10;  
    }
    
    void main(void)
    {
    int   a = 10;      // Entier codé sur 16 bits
    short b = 30;      // Entier codé sur 8 bits
    
    
    Ma_fonction(a);
    Ma_fonction(b);
    }

    code éventuellement à tuner, pas de moyen de tester ce moment.
    Heu... C'est la solution que j'avais déjà donnée au post #5... et que j'avais testée.

  16. #15
    albanxiii

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Citation Envoyé par PA5CAL Voir le message
    Heu... C'est la solution que j'avais déjà donnée au post #5... et que j'avais testée.
    Vous n'aviez jamais remarqué que beaucoup répondent sans avoir lu le réponses déjà données ?
    Not only is it not right, it's not even wrong!

  17. #16
    jacknicklaus

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Citation Envoyé par PA5CAL Voir le message
    Heu... C'est la solution que j'avais déjà donnée au post #5... et que j'avais testée.
    oups !
    désolé
    There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.

  18. #17
    mweber

    Re : Passage par adresse de paramètre dans une fonction, un doute me taraude...

    Bon en tout cas merci pour vos idées.

    Je ne pouvais par contre pas créer 2 fonctions car elle est bien plus complexe en réalité...
    Même en factorisant des parties j'étais perdant en ROM par rapport aux soluces proposées

    Bon je suis un tantinet taré de coller dans un PIC à 64 ko de ROM, la gestion d'un poêle à pellet + panneau solaire thermique + chauffage avec écran tactile couleur carte SD et Wifi !

    Sans y aller avec une Raspberry PI, une Arduino méga avec un shield fait maison aurait été..

    Mais n'en'pêche tout mon programme tient dans les 64 ko !

    Matt

Discussions similaires

  1. Passage paramètre sqlplus
    Par Lechero dans le forum Programmation et langages, Algorithmique
    Réponses: 2
    Dernier message: 23/11/2015, 08h16
  2. Passer une adresse en paramètre d'une fonction au lieu d'un tableau (langage C)
    Par CyrilV dans le forum Programmation et langages, Algorithmique
    Réponses: 2
    Dernier message: 02/08/2014, 17h43
  3. Doute sur mes résultats et sur mon passage en L2
    Par Lamelune dans le forum Orientation après le BAC
    Réponses: 3
    Dernier message: 09/07/2011, 10h29
  4. passage de vis ou trou taraudé?
    Par abdannour dans le forum Technologies
    Réponses: 16
    Dernier message: 20/08/2008, 21h12
  5. Passage à la puissance n, doute
    Par Claudinne dans le forum Mathématiques du supérieur
    Réponses: 3
    Dernier message: 30/12/2005, 12h47