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 :

plusieurs return dans une fonction?


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut plusieurs return dans une fonction?
    Je venais d'ecrire la fonction ci-dessous que je suis tombé sur :
    http://emmanuel-delahaye.developpez.com/goret.htm
    Force 8
    * Plus d'un return par fonction
    Cette fonction retourne la distance minimum entre :
    - p + d
    et
    - centre

    Sachant que -1 représente l'infini.

    Il me semble que les return évitent des tests inutiles.

    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
     
    static inline int min_dist(int centre, int p, int d) {
        if(centre == -1) {
    	if(p == -1) {
    	    return centre; //j'aurai pu ecrire return -1 c'est pareil
    	}
    	return p+d;
        }
        if(p == -1) {
    	return centre;
        }
        if(p+d < centre) {
    	return p+d;
        }
        return centre;
    }
    Accessoirement je ne comprends pas trop ceci aussi :
    Utilisation du type int ou long pour les index.
    J'ai toujours vu des int pour les index, quel est le problème sachant que la manipulation d'un int n'est pas plus lente qu'un autre type?

  2. #2
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Je venais d'ecrire la fonction ci-dessous que je suis tombé sur :
    http://emmanuel-delahaye.developpez.com/goret.htm
    Cette page contient l'avis personnel d'Emmanuel Delahaye. Certains conseils relevent du bon sens, d'autres sont plus une question de style. N'avoir qu'un seul return par fonction est une question de style. Tu fais ce que tu veux.

    Dans ton cas, n'avoir qu'un seul return est trivial:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    static inline int min_dist(int centre, int p, int d) {
       int ret = centre;
     
        if((centre == -1 && p != -1) ||
           (p+d < centre))
        {
    	ret = p+d;
        }
        return ret;
    }

  3. #3
    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
    Personnellement, je trouve que utiliser une seule instruction return par fonction clarifie le code. En effet, selon les principes fondamentaux de la programmation structurée, une fonction doit posséder un seul point d'entrée et un seul point de sortie. Mais ne soyons pas dogmatiques, et comme le dit très bien DaZumba, c'est essentiellement une question de style et de goût personnel. D'autres personnes trouvent que la présence de multiples return clarifie le code, moi pas.

    En ce qui concerne les indices, j'utilise généralement le type size_t.

    Thierry

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Dans ton cas, n'avoir qu'un seul return est trivial:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    static inline int min_dist(int centre, int p, int d) {
       int ret = centre;
     
        if((centre == -1 && p != -1) ||
           (p+d < centre))
        {
    	ret = p+d;
        }
        return ret;
    }
    Pas si trivial que ca car il faut gerer l'infini représenté par -1.
    Ici, si p == -1 et centre > p+d tu retournes p+d ce qui sera faux.

  5. #5
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Pas si trivial que ca car il faut gerer l'infini représenté par -1.
    Ici, si p == -1 et centre > p+d tu retournes p+d ce qui sera faux.
    Ah oui, je me suis fait avoir pour le troisieme return
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    static inline int min_dist(int centre, int p, int d)
    {
       int ret = centre;
     
        if(p != -1 && (centre == -1 || p+d < centre))
        {
    	ret = p+d;
        }
        return ret;
    }

  6. #6
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Dans l'embarqué, l'optimisation du code est un critères important dans le choix d'un compilateur.

    Pour une fonction à plusieurs return, le débogueur sera incapable de suivre pas à pas le code puisque qu'il est très fortement modifié par l'optimiseur, en particulier les return qui risquent de se transformer en un seul return. Ce qui fait souvent dire que le débogueur ne marche pas, ce qui est faux, puisqu'il suffit de désactiver l'optimiseur pour que tout rentre dans l'ordre.

    Il en est de même pour les variables modifiées mais non lues que l'on crée pour déboguer. Si elle ne sont jamais lues, l'optimiseur les supprimera purement et simplement du code d'où là aussi un comportement indéterminé en mode pas à pas.

    A+

    Pfeuh

  7. #7
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2007
    Messages
    979
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 979
    Points : 1 256
    Points
    1 256
    Par défaut
    je vous avoue que c'est la première fois que j'entends dire que plusieurs return dans une même fonction était déconseillé .

    j'ai souvent plusieurs return dans mes méthodes pour plusieurs raisons. Entre autre gérer les cas particuliers (variable d'entrée mal conditionner ou cas intraitable).

    Je trouve mieux un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    double  inverse(double x)
    {
      if(x == 0.0) {
        return 0.0;
      }
      return 1/x ;
    }
    que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    double  inverse(double x)
    {
      double y = 0.0;
      if(x != 0.0) {
        y = 1/x;
      }
      return y;
    }
    ++

  8. #8
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    L'objectif c'est pas d'avoir un ou plusieurs return mais du code lisible. Des deux écritures on préferera donc celle qui rendra le code plus lisible. Ca peut être l'un, ça peut être l'autre ...

  9. #9
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    mr_samurai :
    j'ai souvent plusieurs return dans mes méthodes pour plusieurs raisons. Entre autre gérer les cas particuliers (variable d'entrée mal conditionner ou cas intraitable).
    Dans ce cas tu as tes return en début de fonction où leur présence est facilement détectable et interprétable par le lecteur : C'est en quelque sorte une phase de validation de la fonction. Ca peut éviter d'imbriquer des blocs qui peuvent alourdir la lisibilité de la "partie essentielle" de la fonction. Je n'ai personnellement rien à reprocher à cette méthode.
    Par contre, je suis beaucoup plus réticent sur le fait d'avoir ensuite d'autres return "cachés" dans les blocs de la "partie essentielle" de la fonction.

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mr_samurai Voir le message
    Je trouve mieux un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    double  inverse(double x)
    {
      if(x == 0.0) {
        return 0.0;
      }
      return 1/x ;
    }
    que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    double  inverse(double x)
    {
      double y = 0.0;
      if(x != 0.0) {
        y = 1/x;
      }
      return y;
    }
    ++
    et :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    double  inverse(double x)
    {
      double res ;
     
      if(x == 0.0)
           res= 0.0;
      else 
           res = 1/x ;
     
      return res ;
    }
    Sinon, comme il a ete dit, tout depend du contexte, d ela fonction, de sa longueur, etc etc...

    Quant a la question d'optimisation, ON NE VAS PAS REVENIR DESSUS : a part cas tres tres tres particuliers, ce genre de choses compelxifient et n'accelerent pas.... L'optimisation vient a 99.99999 % des cas de l'algo, pas de son ecriture...

  11. #11
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2007
    Messages
    979
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 979
    Points : 1 256
    Points
    1 256
    Par défaut
    oki, je vois bien ce que vous voulez dire.

    Je suis d'accord avec vous sur ce point. Personnellement, je n'utilise return que pour la validation de entrées, et des cas de switch.

  12. #12
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 723
    Points
    5 723
    Par défaut
    beh moi ca dépend des cas, prenons l'exemple d ela bibliothéque standard la fonction strcmp.

    voici une tentative de réécriture de la fonction, est-ce que vous saurez faire plus lisible avec 1 return

    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
    20
    21
    22
    23
    24
    25
    static inline int my_strcmp(const char * const s1,const char * const s2) {
     
        int i;
        i=0;
        while(s1[i]!='\0' && s2[i]!='\0') {
            if(s1[i]<s2[i])
                return -1; /* on quitte la fonction */
            else
                if (s1[i]>s2[i])
                    return 1;
     
            /* caractère identique */
            i++;
        }
     
     
        /* causes de la sortie de boucle */
        if(s1[i]!='\0' && s2[i]=='\0')
            return 1;
                   else if(s1[i]=='\0' && s2[i]!='\0')
                       return -1;
     
        return 0;
     
    }
    Le risque avec plusieurs return est que tu oublies un cas ce qui fait que pendant l'execution ta fonction ne renvoi rien du tout, normalement avec les options du compilateur ces warnings sont détectables

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mr_samurai Voir le message
    oki, je vois bien ce que vous voulez dire.

    Je suis d'accord avec vous sur ce point. Personnellement, je n'utilise return que pour la validation de entrées, et des cas de switch.
    pour les switch, au contraire, c'est tellement facile de mettre un statut et de retourner une seule fois le statut a la fin...

    La validation d'entrees, peut-etre...

    C'est a mon avis surtout utilisable en debut de fonction necessitant soit un grand nombre de parametres ou d'allocations, qui ferait trop de if pour tout prendre en compte ... soit une serie de conditions rendant caduqye le traitement situe plus bas...

  14. #14
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par hegros Voir le message
    beh moi ca dépend des cas, prenons l'exemple d ela bibliothéque standard la fonction strcmp.

    voici une tentative de réécriture de la fonction, est-ce que vous saurez faire plus lisible avec 1 return
    Hmm:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int my_strcmp(const char *s1, const char *s2)
    {
      while (*s1 != '\0' && *s1 == *s2)
      {
        s1++;
        s2++;
      }
     
      return (*(unsigned char *) s1) - (*(unsigned char *) s2);
    }
    (note que strcmp() ne renvoie pas forcement -1, 0, ou 1).

    EDIT: Correction (pointeurs const dans le prototype retirés.)

  15. #15
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Melem Voir le message
    L'objectif c'est pas d'avoir un ou plusieurs return mais du code lisible. Des deux écritures on préferera donc celle qui rendra le code plus lisible. Ca peut être l'un, ça peut être l'autre ...
    +1

  16. #16
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 723
    Points
    5 723
    Par défaut
    **

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Accessoirement je ne comprends pas trop ceci aussi :
    Utilisation du type int ou long pour les index.
    J'ai toujours vu des int pour les index, quel est le problème sachant que la manipulation d'un int n'est pas plus lente qu'un autre type?
    Ce n'est pas une question de lenteur mais de compatibilité ascendante. Aujourd'hui la taille maximale d'un tableau dépasse le simple int et est de l'ordre du long donc déjà pour que ton code fonctionne encore dans les cas extrèmes, il te faut remplacer tes "int i" par des "long i". Et accessoirement étant donné qu'un indice est toujours positif, le unsigned peut être utile.
    Maintenant que se passera-t-il demain lorsque les architectures 64 deviendront un standard et que ton tableau pourra atteindre le 2^64 bits ? Faudra remplacer tes long par le nouveau type qui va bien.

    Pour éviter ce problème, il existe le type "size_t" qui est suffisemment grand pour gérer l'ensemble d'un tableau aujourd'hui. Et si demain l'ensemble change, le type sera modifié en conséquence. Donc si tu définis tes index de type "size_t" ton code suivra l'évolution des systèmes sans que t'aies besoin de le modifier.

    Là où parfois j'ai des problèmes, c'est quand je définis une fonction qui renvoie l'index d'un élément du tableau. La fonction est donc de type size_t. Mais quand elle ne trouve pas l'élément voulu il faut qu'elle renvoie une valeur spéciale. Mais je peux pas lui faire renvoyer "-1" car il n'est pas de type size_t (unsigned long).

  18. #18
    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
    Tu peux toujours retourner SIZE_MAX, défini dans limits.h...

  19. #19
    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 Médinoc Voir le message
    Tu peux toujours retourner SIZE_MAX, défini dans limits.h...
    ou ((size_t)-1) si tu n'as pas C99...

  20. #20
    Membre confirmé Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Points : 567
    Points
    567
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Aujourd'hui la taille maximale d'un tableau dépasse le simple int et est de l'ordre du long donc déjà pour que ton code fonctionne encore dans les cas extrèmes, il te faut remplacer tes "int i" par des "long i". Et accessoirement étant donné qu'un indice est toujours positif, le unsigned peut être utile.
    Maintenant que se passera-t-il demain lorsque les architectures 64 deviendront un standard et que ton tableau pourra atteindre le 2^64 bits ? Faudra remplacer tes long par le nouveau type qui va bien.
    Ça dépend d'à quoi sert le tableau. Si il contient des trucs sur les mois de l'année tu crois vraiment qu'il risque un jour de contenir plus de 2^16 éléments ? Personnellement j'utilise presque tout le temps unsigned int.
    Pour le moment en mode 64 bits on n'a "que" 48 bits d'adressage. Tu te rends compte de la quantité que ça fait 2^64 ?

Discussions similaires

  1. Plusieurs return dans une fonction
    Par ninikkhuet dans le forum Langage
    Réponses: 4
    Dernier message: 19/05/2010, 12h45
  2. syntaxe plusieurs instructions dans une fonction
    Par sebac dans le forum Général JavaScript
    Réponses: 17
    Dernier message: 02/03/2010, 12h55
  3. plusieurs return dans une seule fonction?
    Par grodashe dans le forum Débuter
    Réponses: 4
    Dernier message: 01/01/2010, 17h09
  4. [AJAX] recuperer plusieurs valeurs dans une fonction
    Par tortue_22 dans le forum AJAX
    Réponses: 4
    Dernier message: 17/05/2009, 13h48
  5. valeur du return dans une "fonction"
    Par Papy214 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 20/12/2007, 15h53

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