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

Bibliothèque standard C Discussion :

strcmp : différentes valeurs de retour dans un cas spécifique


Sujet :

Bibliothèque standard C

  1. #1
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut strcmp : différentes valeurs de retour dans un cas spécifique
    Bonsoir,

    j ai note une difference de resultats pour strcmp selon l os sur lequel je me trouvais :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char *s1 = "125";
    char *s2 = "123";
    printf("%i\n", strcmp(s1, s2));
    printf("%i\n", strcmp("125", "123"));

    Sous mac : strcmp retourne bien une difference de 2 dans les deux cas d utilisation.
    Sous linux : strcmp retournera 1 et non 2 lorsque l on cree directement les string dans les parametres.

    Strcmp sous apple :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int
    strcmp(s1, s2)
    	const char *s1, *s2;
    {
    	while (*s1 == *s2++)
    		if (*s1++ == 0)
    			return (0);
    	return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
    }

    L implementation GNU :

    Code c : 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
     
    int
    STRCMP (const char *p1, const char *p2)
    {
      const unsigned char *s1 = (const unsigned char *) p1;
      const unsigned char *s2 = (const unsigned char *) p2;
      unsigned char c1, c2;
     
      do
        {
          c1 = (unsigned char) *s1++;
          c2 = (unsigned char) *s2++;
          if (c1 == '\0')
    	return c1 - c2;
        }
      while (c1 == c2);
     
      return c1 - c2;
    }


    Le comportement du code reste relativement le meme dans les deux versions. Qu est ce qui cause cette difference ? Le code genere par les compilateurs ? L architecture des processeurs ? Ou me manque il simplement une notion que je n ai pas encore etudiee ?

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 584
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 584
    Points : 7 721
    Points
    7 721
    Par défaut
    Et en activant les optimisations les 4 appels devraient retourner 1.
    Le compilateur voit bien que l'on veut comparer "123" avec "125", c'est plus facile pour lui dans le second cas. Il connait la réponse il faut retourner un nombre positif, il va souvent choisir le 1 et n'a aucune raison d'appeler la fonction strcmp() et va produire une code équivalent à printf("%i\n",1);.

  3. #3
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 745
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 745
    Points : 43 881
    Points
    43 881
    Par défaut
    Extrait du man :
    Les fonctions strcmp() et strncmp() renvoient un entier inférieur, égal ou supérieur à zéro si s1 (ou ses n premiers octets) est respectivement inférieure, égale ou supérieure à s2.
    Si les chaines sont égales, le retour sera 0, sinon inférieur ou supérieur à 0 sans précision de valeur.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 055
    Points
    33 055
    Billets dans le blog
    4
    Par défaut
    La doc indique très clairement que si les chaînes sont égales la valeur retournée est 0, mais il n'y a aucune raison de croire que seules les valeurs -1 et +1 peuvent être retournées quand elles ne le sont pas.
    Certaines implémentations font sûrement ce choix, d'autres se contentent de retourner la différence entre les 2 caractères différents et peuvent donc retourner des valeurs bien plus grandes (et tu peux toi-même voir l'implémentation choisie et en tirer cette conclusion).

    http://www.cplusplus.com/reference/cstring/strcmp/

  5. #5
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Bonjour bousk, dans l implementation de la libc qu utilise mac, la fonction opere le meme traitement que pour la glibc, a savoir retourner la difference par soustraction. Ce n etait pas ca le soucis en l occurence, comme l a souligne dalfab. Mais merci pour ce rappel.


    Citation Envoyé par dalfab Voir le message
    Et en activant les optimisations les 4 appels devraient retourner 1.
    Le compilateur voit bien que l'on veut comparer "123" avec "125", c'est plus facile pour lui dans le second cas. Il connait la réponse il faut retourner un nombre positif, il va souvent choisir le 1 et n'a aucune raison d'appeler la fonction strcmp() et va produire une code équivalent à printf("%i\n",1);.
    Bonjour dalfab et merci pour ta reponse. Effectivement en appliquant une optimisation de niveau 1 alors les deux cas n appellent plus directement la fonction. comme tu l avais predit. Je m etais rendu compte de cette difference dans un projet pour mon ecole ou je dois recoder un certains nombre de fonctions de manipulation de string et de zone memoire de la lib standard, et le jour ou j ai lance ma serie de tests sous linux, les resultats de la fonction strcmp standard ne correspondaient plus au resultat de mon strcmp alors que sous mac oui, d ou mon etonnement.

    Comment dois je interpreter cette difference de traitement par gcc mac et gcc linux ? Dois je en conclure, par les resultats obtenus, que gcc sous mac n inclut pas certains traitements d optimisation de compilation qui sont presents par defaut pour gcc sur des distro linux ?
    Ce traitement d optimisation etant present par defaut sur mon linux, est il possible de le desactiver (je suis novice dans l utilisation de gcc j apprivoise la bete petit a petit) ?

  6. #6
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 745
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 745
    Points : 43 881
    Points
    43 881
    Par défaut
    Pour bien comprendre, strcmp retourne 0 en cas de comparaison ok et n'importe quel nombre positif ou négatif si les chaines diffèrent. La fonction n'est pas censée retourner la position de divergence, le nombre de caractères comparées, ou autre chose.

    Les deux implémentations, bien que différentes et ne retournant pas la même valeur en cas de comparaison infructueuse, sont bonnes. Dans ton implémentation, tu peux retourner n'importe quel valeur positive (si la chaine en premier argument est considérée supérieure à la seconde chaine) ou négative différente de 0 en cas de chaines différentes, elle sera tout aussi valable que les autres.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 055
    Points
    33 055
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Benbout Voir le message
    Comment dois je interpreter cette difference de traitement par gcc mac et gcc linux ? Dois je en conclure, par les resultats obtenus, que gcc sous mac n inclut pas certains traitements d optimisation de compilation qui sont presents par defaut pour gcc sur des distro linux ?
    Ce traitement d optimisation etant present par defaut sur mon linux, est il possible de le desactiver (je suis novice dans l utilisation de gcc j apprivoise la bete petit a petit) ?
    Tu dois purement et simplement l'ignorer et te contenter de suivre la doc : 0 signifie chaînes identiques, autre chose signifie qu'elles sont différentes.
    Si le compilateur optimise des morceaux, tant mieux et c'est aussi son boulot
    https://stackoverflow.com/a/27751263

    Si tu ne veux pas ça, peut-être qu'en changeant le nom de la fonction le compilateur ne la reconnaîtra pas et arrêtera d'utiliser son intrinsic à la place ? (Normalement on fait l'opération inverse, parce que les intrinsic sont des gains de perf )

  8. #8
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Apres la lecture d un e-book sur l optmisation des compilateurs (dispo sur developpez.net il faut le souligner), je comprend mieux quels en sont les mecanismes. Cela reste un peu deroutant dans le cas de strcmp car la documentation s attache a decrire le comportement d une fonction (normallement isolee de son environnement) et pour le coup elle decrit le comportement d une fonction sous l influence supposee de facteurs exterieurs impliquant le compilateur, car la fonction, prise de maniere isolee, correspond a la documentation mais son implementation se veut plus precise que la documentation seule. Je ne comprend toujours pas, d ailleurs, pourquoi la fonction ne retourne tout simplement pas -1 0 ou 1, ce qui correspondrait toujours au comportement qu on lui a impose tout en etant plus rapide a l execution, et semblerait plus logique car en prenant comme reference la documentation le fait que la fonction retourne un entier de n importe quelle valeur (n importe quel entier positif si s1 est superier a s2 par exemple), n apporte rien de concret au programmeur, puisque cette valeur n est pas predictible si l on s en tient a la doc. Le developpeur fera toujours la meme chose, a savoir checker si le resultat est < > ou = a 0. Si vous avez une derniere reponse a ajouter a ce sujet n hesitez pas ! (pardonnez moi pour le massacre de la syntaxe de notre belle langue je suis sous clavier us en ce moment).

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    Ton dernier message est plutôt capilotracté....

    pourquoi la fonction ne retourne tout simplement pas -1 0 ou 1, ce qui correspondrait toujours au comportement qu on lui a impose tout en etant plus rapide a l execution
    Non, on lui impose de renvoyer 0 ou un nombre positif ou un nombre négatif, pas -1, 0 ou 1 :
    https://man.developpez.com/man3/strcmp/
    4. VALEUR RENVOYÉE
    Les fonctions strcmp() et strncmp() renvoient un entier inférieur, égal ou supérieur à zéro si s1 (ou ses n premiers octets) est respectivement inférieure, égale ou supérieure à s2.
    Et aucune garantie que renvoyé -1, 0 ou 1 serait plus rapide... Pourquoi dis-tu cela d'ailleurs ?

    son implementation se veut plus precise que la documentation seule
    Gné ? Qu'est ce que cela veut dire ?

    n apporte rien de concret au programmeur, puisque cette valeur n est pas predictible si l on s en tient a la doc
    Elle est totalement prédictible : négative, nulle ou positive.

  10. #10
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Non, on lui impose de renvoyer 0 ou un nombre positif ou un nombre négatif, pas -1, 0 ou 1 :
    https://man.developpez.com/man3/strcmp/
    Et pourquoi pas ? -1 0 ou 1, c est n importe quel entier negatif ou positif. Si j implemente la fonction de cette maniere elle respectera la doc. Et c est ce que fait le compilateur si ses optimisations sont actives de toute facon donc pourquoi ne pas le faire par defaut ? Comme je l ai dit une valeur autre que -1 0 ou 1 n a aucun interet pour le programmeur puisqu il n est pas capable de predire la valeur exacte en sortie (predire n est peut etre pas le mot que je suis cense utiliser), juste si ce sera superieur egal ou positif par rapport a une reference en l occurence le chiffre 0, donc outre ce fait, que la fonction renvoie 40 ou -45 n a aucune utilite, ce n est pas utilisable dans le contexte exprime par la doc.

    J ai bien compris la doc, mais il me semble qu il est naturel de se poser cette question. Je n ai pas pour habitude de m en tenir a "parce que la doc le dit". Je cherche a comprendre pourquoi il en est ainsi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Et aucune garantie que renvoyé -1, 0 ou 1 serait plus rapide... Pourquoi dis-tu cela d'ailleurs ?
    N est il pas plus rapide de renvoyer une constante plutot qu une soustraction de deux nombres ? C est ce que fait le compilateur quand ses optimisations sont actives non ?

  11. #11
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Benbout Voir le message
    Et pourquoi pas ?
    Parce que ça ne respecterait pas le principe de parcimonie ! Le rasoir d'Ockham nous dit qu'il faut nous en tenir à ce qui est strictement nécessaire. Si l'on peut décrire un comportement en requérant le respect de n contraintes, pourquoi en imposer n + 1 ?

    S'en tenir à un ensemble minimal laisse la plus grande liberté à l'implémentation et donc le champ libre à un plus grand nombre de possibilités d'optimisation. Tu pars du principe que renvoyer (-)1 est toujours le meilleur choix. C'est pour le moins péremptoire, et probablement faux.

  12. #12
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Merci Matt. Prenons le cas ou c est faux, finalement oublions les questions de rapidite et tutti quanti. Prenons l exemple suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char s1[] = "toto";
    char s2[] = "tota";
    int r = strcmp(s1, s2);
    Es tu capable de predire la valeur de retour ? Non.
    Tu es en mesure d affirmer que r sera superieur a 0, car s1 est superieur a s2 par comparaison lexicolographique.
    Si r = -45, la valeur absolue de -45 t es t elle utile ? Non car tu n es pas en mesure de predire dans quelles circonstances -45 est retourne. -45 et -78 sont donc egaux dans le contexte d utilisation de la fonction.

    Prenons desormais la fonction isascii. Elle renvoie 0 si le char n est pas ascii et 1 si c est le cas.
    Il aurait pu etre convenu que isascii renvoie n importe quel entier positif si le char est un ascii et n importe quel entier negatif si ce n est pas le cas. Pourtant, comme bons nombre de fonctions de comparaison, ce n est pas le choix qui a ete fait et c est facilement justifiable. La fonction repond a une problematique qui est "est ce un caractere ascii ?" A cela 2 solutions possibles Oui ou non. Cela se traduit par le renvoi de deux nombres distincts indiquant le oui ou le non. A t on besoin d une infinite de valeur pour caractericer ces deux etats ? Non. La fonction strcmp est quasiment equivalente excepte qu il n y a pas deux etats mais trois. Sommes nous dans la necessite d utiliser une infinite de valeurs pour caracteriser ces trois etats ? Non.

    Ce que j essaie de comprendre, c est pourquoi est ce le cas ? Si la reponse est simplement : "parce que des developpeurs se sont reunis et ont decide que ce serait comme ca sans nous faire parvenir des justifications quand au raisonnement qui a donne lieu a ce choix", alors la discussion s arretera la, mais s il y a une raison technique derriere cela, et il y en a forcement une j aurais evidemment aime la connaitre.

  13. #13
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 901
    Points : 219 894
    Points
    219 894
    Billets dans le blog
    125
    Par défaut
    Bonjour,

    Avez-vous essayé d'écrire le code de strcmp() ? C'est "intéressant" (on peut aussi le trouver sur Internet).
    Je vais y revenir.

    Prenons desormais la fonction isascii. Elle renvoie 0 si le char n est pas ascii et 1 si c est le cas.
    Je me demande quelle doc vous lisez. Voici la mienne :
    The values returned are nonzero if the character c falls into the tested class, and a zero value if not.
    Revenons au strcmp(), je vais faire une implémentation naïve :
    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
    int strcmp(const char* str1, const char* str2)
    {
        int length = min(strlen(str1), strlen(str2)); // on va dire que min existe, sinon c'est juste un if ;)
     
        for(int i = 0; i < length ; i++)
        {
            if(str1[i] != str2[i])
            {
                 if(str1[i] < str2[i])
                     return -1;
                 else
                     return 1;
            }
        }
        return 0;
    }
    C'est naïf, mais ça retourne que des -1, 1, 0. Normalement, ce genre d'implémentation est réalisée avec des pointeurs qui se déplacent sur le tableau (et on incrémente les pointeurs), mais je voulais vraiment faire naïvement.

    On voit que le test dans la boucle pourrait être améliorée par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(str1[i] != str2[i])
    {
         return str1[i] - str2[i];
    }
    En laissant libre les valeurs de retour, on peut réduire le code, et possiblement réduire le temps d'exécution. Bien entendu, ce n'est pas exactement ça dans la réalité, et je vous invite à regarde une implémentation officielle. Toutefois, le fait de remplacer un test par une soustraction sera certainement une habitude retenue, car on pourra faire un do...while() avec comme condition, le résultat de la soustraction (on continue tant qu'il est égal à 0 et sinon, on le retourne dès que l'on sort du while(). Soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    do
    {
        res = str1[i] - str2[i]
    }while(res == 0 && str1[i] != '\0')
    return res;
    J'ai oublié de dire, votre code présenté ci-dessus sera certainement optimisé par le compilateur, pour une exécution lors de la compilation. En effet, le compilateur peut embarquer une implémentation de certaine fonction, comme strcmp, dont le résultat est toujours le même, car vos chaines sont hardcodés .

  14. #14
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Bonsoir Littlewhite. Oui j ai du implementer la fonction parmi une soixantaine d autres fonctions de la libc. C est justement en implementant ma version (qui est sensiblement la meme que celle de la gnu libc mis a part le do while que je n ai pas le droit d utiliser) que j ai eu des failures lors de tests unitaires, suivant le niveau d optimisation du compilateur la fonction standard n avait plus le meme comportement que ma fonction (j appris plus tard grace a un intervenant que la fonction n etait pas en cause d ailleurs, c etait simplement le compilateur), et bien que cela corresponde toujours au comportement de la documentation, cela m a amene a ouvrir une discussion pour comprendre pourquoi ce comportement changeait.
    Et pour isascii vous avez absolument raison je viens de regarder mon man c est le meme c est une erreur grossiere de ma part. Le C est le premier langage de bas niveau que j aborde et c est la premiere fois que je fais face a des fonctions qui dans d autres langages renverrait simplement true ou false, ou 0 ou 1, alors pour moi il me semble plus logique de renvoyer deux valeurs simples, constantes, 0 ou 1 pour signifier signifier qu un char est ascii ou non par exemple. Cette idee de renvoyer une infinite d entiers positif possibles pour affirmer qu un char est ascii me laissait dubitatif (du moins jusqu a maintenant).

  15. #15
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    Il en faut pas confondre spécification d'une fonction et les détails des implémentations possibles. En disant "la fonction renvoie un nombre négatif, zéro ou un nombre positif", tu laisses plus de possibilités aux personnes qui vont écrire la bibliothèque standard pour une cible particulière que si tu dis "la fonction renvoie -1, 0 ou 1". C'est ce que montre LittleWhite. Une implémentation pourra choisir de renvoyer -1,0 et 1 ; une autre pourra choisir de renvoyer -174652, 0 et 42 ; une dernière des valeurs non constantes (par exemple les différences entre caractères). Toutes seront correctes et chacune aura peut-être ses avantages pour sa cible.

    Il ne faut pas perdre de vue que le C est un langage bas niveau, qui se veut être facile à porter sur une nouvelle cible. La norme laisse beaucoup de zone assez "floues". Par exemple, il suffit de compter le nombre d'occurrences de l'adjectif "implementation-defined" le document n1256 (la norme C99) pour s'en convaincre : 160 !

    Quant à savoir s'il aurait été plus judicieux de spécifier dans la norme "strcmp() doit renvoyer -1, 0 et 1" pour que les valeurs soient utilisables, c'est peut-être que tu cherches quelque chose qui n'est pas le but de la fonction. Le but de n'est pas d'avoir un multiplicateur (car c'est vrai que -1, 0 et 1, ça serait carrément pratique dans certains cas ) pour faire des opérations directement. Le but est de comparer des chaines. Après, rien ne t'empêches d'écrire ta propre fonction utilitaire :
    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
    #include <string.h>
     
    int compareStrings(const char* lhs, const char* rhs)
    {
        int c = strcmp(lhs, rhs);
     
        if (c < 0)
        {
            return -1;
        }
        else if (c > 0)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
     
    int main() {
        return compareStrings("hello", "world");
    }
    Quand à savoir si le C n'est pas précis par rapport à d'autres langages de plus haut niveau, on pourra String.compareToIgnoreCase() de Java :
    Returns:
    a negative integer, zero, or a positive integer as the specified String is greater than, equal to, or less than this String, ignoring case considerations.
    Hasard ou simplicité pour être implémentée grâce à strcmp() de C, je te laisse décider

    En Python, tu n'as pas de telles fonctions, tu compares avec <, <=, !=, ==, >=, > directement et tu obtiens des booléens.

  16. #16
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Quant à savoir s'il aurait été plus judicieux de spécifier dans la norme "strcmp() doit renvoyer -1, 0 et 1" pour que les valeurs soient utilisables, c'est peut-être que tu cherches quelque chose qui n'est pas le but de la fonction.
    Effectivement.

    Il ne faut pas perdre de vue que le C est un langage bas niveau, qui se veut être facile à porter sur une nouvelle cible. La norme laisse beaucoup de zone assez "floues". Par exemple, il suffit de compter le nombre d'occurrences de l'adjectif "implementation-defined" le document n1256 (la norme C99) pour s'en convaincre : 160 !
    Les fameux "undefined behaviour" sont aussi une specialite du standard j ai l impression ! Merci pour ce complement d informations c est en tout point ce que j attendais !

  17. #17
    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
    Attention! Il ne faut pas confondre implementation-defined et undefined. Surtout de nos jours, où un compilateur moderne suppose que les comportements indéfinis ne peuvent pas arriver lors qu'ils font leurs optimisations...

  18. #18
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 726
    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 726
    Points : 31 046
    Points
    31 046
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Bktero Voir le message
    La norme laisse beaucoup de zone assez "floues"
    Pour ma part j'ai connu une fonction strcmp() qui renvoyait la position du caractère qui diffère (position commençant bien évidemment à 1). Ce qui ne m'a d'ailleurs jamais servi.

    Citation Envoyé par Bktero Voir le message
    En Python, tu n'as pas de telles fonctions, tu compares avec <, <=, !=, ==, >=, > directement et tu obtiens des booléens.
    As-tu remarqué que cela est un "moins" par rapport au C ? En C tu as d'un seul coup les 3 infos "plus petit" ou "égal" ou "plus grand". Tu peux donc switcher sur les 3 alternatives en un seul test. En Python il t'en faudra deux. Quel dommage pour un aussi chouette langage...

  19. #19
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    Tu t'en fiches t'as pas de switch/case en Python

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

Discussions similaires

  1. [WD15] Récupérer valeur de retour dans procédure stockée
    Par deepshark dans le forum WinDev
    Réponses: 1
    Dernier message: 15/02/2012, 11h23
  2. Réponses: 6
    Dernier message: 29/08/2007, 06h49
  3. Réponses: 1
    Dernier message: 16/03/2007, 11h46
  4. Réponses: 3
    Dernier message: 13/12/2006, 18h05
  5. Réponses: 3
    Dernier message: 06/10/2005, 15h21

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