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 :

conseils sur quelques macros


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut conseils sur quelques macros
    Bonjour, dans mon prgm, j'aimerais faire qq macros. Lorsque je fais un malloc, mon code est le suivan :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    T * p=malloc(N*sizeof(*p));
    if(p==NULL)
    {
      fprintf(stderr,"%s:%d : Error : malloc() failed\n",__FILE__,__LINE__);
      exit(EXIT_FAILURE);
    }
    d'où ma macro suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #define MEMERROR \
    do\
    {\
      fprintf(stderr,"%s:%d : Error : malloc() failed\n",__FILE__,__LINE__);\
      exit(EXIT_FAILURE);\
    }\
    while(0)
     
    T * p=malloc(N*sizeof(*p));
    if(p==NULL) MEMERROR;
    Serait-il maintenant possible de faire une macro du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    T * p=MALLOC(p,N);
    où la macro MALLOC fait qqch du genre (mais ça ne marche pas...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define MALLOC(ptr,size)\
    do\
    {\
      malloc(size*sizeof(*ptr));\
      ifptr==NULL) MEMERROR;\
    }\
    while(0)
    Bien sûr ceci ne marche pas...


    A propos de free : plutôt que de faire à chaque fois

    puis-je faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define FREE(ptr)\
    do\
    {\
      free(ptr);\
      ptr=NULL;\
    }\
    while(0)
    Enfin, à propos du fclose(), puis-je faire, au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fclose(pfile); pfile=NULL;
    une macro comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define FCLOSE(ptr)\
    do\
    {\
      fclose(ptr);\
      ptr=NULL;\
    }\
    while(0)
    Pouvez-vous donc s'il vous plait me conseiller sur ces macros ? Est-il recommandé de faire autant de macros (elles sont courtes donc lisibles) ?

    Merci d'avance

  2. #2
    Membre Expert
    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
    Par défaut
    Salut,

    A moins de tricher, tu ne peux pas faire "retourner" quelquechose à une macro multi-instruction. Donc pas de
    Je suggererais de faire une fonction inline (ou pas..), mais comme tu as besoin de la ligne et le fichier en cours, il faudrait une macro qui appelle cette fonction et lui passe en paramètre la ligne et le fichier en cours

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define MY_MALLOC(size) my_malloc(size, __FILE__, __LINE__)
     
    static inline void * my_malloc(size_t size, const char * fname, int line) {
       void * ptr;
       ptr = malloc(size);
       if (ptr == NULL)
       {
          fprintf(stderr,"%s:%d : Error : malloc() failed\n",fname,line);
          exit(EXIT_FAILURE);
       }
       return ptr;
    }

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Ah oui, c'est très malin. Je vais essayer ça dès demain au boulot.
    Merci.

  4. #4
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,

    une tite question en passant.

    Pourquoi systématiquement un "do while( 0 )" autour de tes macros ?

  5. #5
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par BainE Voir le message
    Pourquoi systématiquement un "do while( 0 )" autour de tes macros ?
    Voir la reponse de la FAQ C.

  6. #6
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Oui effectivement.

    Jamais eu ce probleme, je mets *toujours* des accolades aux if meme pour une seule instruction (ou meme pas du tout).

  7. #7
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par BainE Voir le message
    Jamais eu ce probleme, je mets *toujours* des accolades aux if meme pour une seule instruction (ou meme pas du tout).
    C'est une bonne habitude, mais tu ne peux pas garantir que tu seras le seul utilisateur des macros que tu definis.

  8. #8
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Oui ca par contre !
    J imagine bien le debbugage de ca ! en plus si la maccro est definie en minuscule, il doit y avoir moyen de s arracher les poils de la tete

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Le seul inconvénient que je connais au do { } while(0) est que ça déclenche le warning "condition constante" de Visual quand celui-ci est activé, et que Visual n'offre rien pour empêcher cela.

    C'est pourquoi j'utilise systématiquement des fonctions inline ou des macros appelant une fonction inline.
    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.

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Re,
    y aurait-il qqun qui sait répondre à mes questions ?
    Je vais essayer ce que tu dis Medinoc

    Merci.

  11. #11
    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 : 48
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par salseropom Voir le message
    Re,
    y aurait-il qqun qui sait répondre à mes questions ?
    Je vais essayer ce que tu dis Medinoc

    Merci.
    Pour les macros FREE et FCLOSE, je ferais comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /* ATTENTION: ces macros evaluent deux fois leur parametre */
    #define FREE(p) ( (p) ), (p)=NULL)
    #define FCLOSE(f) (fclose( (f) ), (f)= NULL)
    En ce qui concerne les macros qui concernent les macros pour *alloc(), tout est dans le tutoriel sur l'allocation dynamique de mémoire de Romuald Perrot: http://rperrot.developpez.com/articl...ocationC/#L4.2.
    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++

    +

  12. #12
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par salseropom Voir le message
    y aurait-il qqun qui sait répondre à mes questions ?
    J'ai du mal a voir l'utilite de macros autour de malloc() et free(), pour etre honnete. Je n'aime pas du tout ton exit(EXIT_FAILURE) en cas d'echec de malloc(): donc, on abandonne tout, on ne libere pas la memoire precedemment allouee, on ne ferme pas les fichiers ouverts, ... Ok, l'OS fera surement cela pour toi, c'est donc plus un probleme de qualite d'implementation, mais je suis d'avis que, notamment dans un projet un peu complexe ou le traitement d'erreur est important (logfile, assurance de l'integrite des donnes input, ...), seul main() devrait avoir le droit de terminer le programme.

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    J'ai du mal a voir l'utilite de macros autour de malloc() et free(), pour etre honnete. Je n'aime pas du tout ton exit(EXIT_FAILURE) en cas d'echec de malloc(): donc, on abandonne tout, on ne libere pas la memoire precedemment allouee, on ne ferme pas les fichiers ouverts, ... Ok, l'OS fera surement cela pour toi, c'est donc plus un probleme de qualite d'implementation, mais je suis d'avis que, notamment dans un projet un peu complexe ou le traitement d'erreur est important (logfile, assurance de l'integrite des donnes input, ...), seul main() devrait avoir le droit de terminer le programme.
    Salut, oui je comprends bien ce que tu dis. Pour ma part, dans mon travail, je fais des programmes pour résoudre des équations (je code des solveurs). Donc, s'il y a une erreur de mémoire, je ne pense pas que ce soit bien grave de stopper brutalement l'exécution.

    En revanche, pour des applications commerciales, ce doit être tout autre chose.

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par Gruik Voir le message
    Salut,

    A moins de tricher, tu ne peux pas faire "retourner" quelquechose à une macro multi-instruction. Donc pas de
    Je suggererais de faire une fonction inline (ou pas..), mais comme tu as besoin de la ligne et le fichier en cours, il faudrait une macro qui appelle cette fonction et lui passe en paramètre la ligne et le fichier en cours

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define MY_MALLOC(size) my_malloc(size, __FILE__, __LINE__)
     
    static inline void * my_malloc(size_t size, const char * fname, int line) {
       void * ptr;
       ptr = malloc(size);
       if (ptr == NULL)
       {
          fprintf(stderr,"%s:%d : Error : malloc() failed\n",fname,line);
          exit(EXIT_FAILURE);
       }
       return ptr;
    }
    Salut, j'ai modifé ta macro comme suit (et ça marche très bien)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #define MY_MALLOC(size) my_malloc(size)
     
    inline void * my_malloc(size_t size) {
       void * ptr = malloc(size);
       if (ptr == NULL)
       {
          fprintf(stderr,"%s:%d : Error : malloc() failed\n",__FILE__,__LINE__);
          exit(EXIT_FAILURE);
       }
       return ptr;
    }
    Merci.

  15. #15
    Membre Expert
    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
    Par défaut
    Alors tu n'as pas besoin de la macro

    Sinon, es tu sur que c'est le bon fichier et la bonne ligne qui sont utilisées?

    A part ça, seul probleme que je vois avec les inline c'est que ça te pourrit un fichier d'en-tete. Rien que pour ça je serais tenté de faire une fonction classique dans un module commun au projet

  16. #16
    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 : 48
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Gruik Voir le message
    Alors tu n'as pas besoin de la macro

    Sinon, es tu sur que c'est le bon fichier et la bonne ligne qui sont utilisées?

    A part ça, seul probleme que je vois avec les inline c'est que ça te pourrit un fichier d'en-tete. Rien que pour ça je serais tenté de faire une fonction classique dans un module commun au projet
    Tu peux peut-être imaginer quelque chose comme cela:

    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
    #if defined(__STDC_VERSION__) && __STDC_VERSION__ <= 199901L
    #  define INLINE inline
    #else
    #  define INLINE static
    #endif
     
    #define MY_MALLOC(size) my_malloc(size, __FILE__, __LINE__)
     
    INLINE void * my_malloc(size_t size, const char * fname, int line) {
       void * ptr;
       ptr = malloc(size);
       if (ptr == NULL)
       {
          fprintf(stderr,"%s:%d : Error : malloc() failed\n",fname,line);
          exit(EXIT_FAILURE);
       }
       return ptr;
    }
    Certains compilateurs optimisent de manière à utiliser une fonction statique comme une fonction inline.

    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++

    +

  17. #17
    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 : 48
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par salseropom Voir le message
    Salut, j'ai modifé ta macro comme suit (et ça marche très bien)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #define MY_MALLOC(size) my_malloc(size)
     
    inline void * my_malloc(size_t size) {
       void * ptr = malloc(size);
       if (ptr == NULL)
       {
          fprintf(stderr,"%s:%d : Error : malloc() failed\n",__FILE__,__LINE__);
          exit(EXIT_FAILURE);
       }
       return ptr;
    }
    Merci.
    Le problème avec ton code, comparé à celui de Gruik, est que __FILE__ et __LINE__ correspondent respectivement au nom du fichier d'en-tête et à la ligne où l'appel à fprintf() est effectué. Avec la version de Gruik, __FILE__ correspond au fichier de la fonction appelante et __LINE__ à la ligne où l'appel est effectué dans ce fichier.

    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++

    +

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Le problème avec ton code, comparé à celui de Gruik, est que __FILE__ et __LINE__ correspondent respectivement au nom du fichier d'en-tête et à la ligne où l'appel à fprintf() est effectué. Avec la version de Gruik, __FILE__ correspond au fichier de la fonction appelante et __LINE__ à la ligne où l'appel est effectué dans ce fichier.

    Thierry
    Ah OK, je n'avais pas fait le test. Merci. Je vais donc reprendre la 1e version de cette macro.

Discussions similaires

  1. [PPT-2002] Conseils sur macro ouverture et fermeture de présentations
    Par Zak_92 dans le forum VBA PowerPoint
    Réponses: 2
    Dernier message: 12/08/2011, 14h35
  2. Quelques conseils sur le graphisme
    Par Sake_reflex dans le forum Android
    Réponses: 8
    Dernier message: 30/06/2011, 10h28
  3. débutant demande conseil sur sa macro
    Par magicfly dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 02/03/2011, 18h58
  4. Quelques questions sur des macro
    Par deubelte dans le forum Débuter
    Réponses: 7
    Dernier message: 17/01/2010, 15h22
  5. Recherche Livre / Conseils sur la conception de Base
    Par Yeuma dans le forum Décisions SGBD
    Réponses: 7
    Dernier message: 02/01/2004, 14h25

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