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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    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
    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 confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 599
    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
    18 212
    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 : 18 212
    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.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    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 147
    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/
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre confirmé
    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
    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
    18 212
    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 : 18 212
    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.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    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 147
    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 )
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre confirmé
    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
    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
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    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.

+ 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